c++ template class member function specialization
我有一个问题,我想在下面的代码中专门化模板类的模板成员函数。对于这个问题的答案,模板类成员函数的显式专门化似乎表明它不能完成。这是正确的吗?如果是的话,我是否可以在编译时通过内联inc函数进行扩展?
多谢!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | #include <iostream> #include <cstdio> template <class IT, unsigned int N> struct IdxIterator { private: int startIdx[N], endIdx[N]; int curIdx[N]; IT iter; public: IdxIterator(IT it, int cur[], int start[], int end[]): iter(it) { for (int i = 0; i < N; i++) { curIdx[i] = cur[i]; startIdx[i] = start[i]; endIdx[i] = end[i]; } } template <int dim> inline void inc() { curIdx[dim]++; if (curIdx[dim] > endIdx[dim]) { if (dim > 0) { curIdx[dim] = startIdx[dim]; inc<dim-1>(); } } } // how to declare this specialization? template <> template <> inline void inc<-1>() { std::cerr <<"IdxIterator::inc(" << -1 <<") dim out of bounds! "; throw 1; } inline IdxIterator<IT, N> operator++() { iter++; inc<N-1>(); return *this; } }; int main(int argc, char** argv) { int *buf = new int[100]; int start[1], end[1]; start[0] = 0; end[0] = 99; IdxIterator<int*, 1> it(buf, start, start, end); ++it; return 0; } |
G+++吐出:
test2.cpp:32:13: error: explicit specialisation in non-namespace scope
‘struct IdxIterator’ test2.cpp:32:25: error: explicit
specialisation in non-namespace scope ‘struct IdxIterator’
test2.cpp:33:23: error: template-id ‘inc<-0x00000000000000001>’ in
declaration of primary template test2.cpp: In member function ‘void
IdxIterator::inc() [with int dim = -0x000000000000003fe, IT =
int*, unsigned int N = 1u]’: test2.cpp:27:9: error: template
instantiation depth exceeds maximum of 1024 (use -ftemplate-depth= to
increase the maximum) instantiating ‘void IdxIterator::inc()
[with int dim = -0x000000000000003ff, IT = int*, unsigned int N = 1u]’
test2.cpp:27:9: recursively instantiated from ‘void IdxIterator::inc() [with int dim = -0x00000000000000001, IT = int*, unsigned
int N = 1u]’ test2.cpp:27:9: instantiated from ‘void IdxIterator::inc() [with int dim = 0, IT = int*, unsigned int N = 1u]’
test2.cpp:41:5: instantiated from ‘IdxIterator
IdxIterator::operator++() [with IT = int*, unsigned int N =
1u]’ test2.cpp:53:5: instantiated from heretest2.cpp: At global scope: test2.cpp:22:15: warning: inline function
‘void IdxIterator::inc() [with int dim = -0x000000000000003ff,
IT = int*, unsigned int N = 1u]’ used but never defined [enabled by
default]
在C++ 11中可能有更好的方法,但是您可以总是通过重载而不是专门化。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | template <int N> struct num { }; class A { template <int N> void f(num <N>) { }; void f(num <-1>) { }; public: template <int N> void f() { f(num <N>()); }; }; |
在类外创建助手结构
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | template<dim> struct inc { template<class cur, end> inline static void foo(cur curIdx, end endIdx) { curIdx[dim]++; if (curIdx[dim] > endIdx[dim]) { inc<dim-1>::foo(curIdx, endIdx); } } }; template<> struct inc<0> { template<class cur, end> inline static void foo(cur, end) { //terminate } }; class IdxIterator { template<int i> void inc() { static_assert(i > 0,"error out of bounds"); int::foo(/*params*/); } }; |
注意:如果您使用GCC,您可以使用cx1(0)强制内联。
您可以按照编译器错误消息的建议进行操作:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | template <class IT, unsigned int N> struct IdxIterator { private: template <int dim> inline void inc() { curIdx[dim]++; if (curIdx[dim] > endIdx[dim]) { if (dim > 0) { curIdx[dim] = startIdx[dim]; inc<dim-1>(); } } } }; template <> template <> inline void IdxIterator::inc<-1>() { std::cerr <<"IdxIterator::inc(" << -1 <<") dim out of bounds! "; throw 1; } |
IE将定义移动到命名空间范围。