c++ template class member function specialization
I have a problem where I want to specialize a template member function of a template class in the code below. The answer to this question explicit specialization of template class member function seems to suggest that it can't be done. Is that correct, and if so, is there any work around I can use so that by inline inc functions get expanded at compile time?
Many thanks!
#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!n";
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++ spits out:
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 here
test2.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中可能有更好的方法,但是你总是可以通过重载来代替专门化:
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>()); };
};
You can do what the compiler error message suggests:
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!n";
throw 1;
}
ie move the definition to namespace-scope.
Create a helper struct outside of class
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<i>::foo(/*params*/);
}
};
Note if you are using the GCC you may __attribute__((always_inline))
to force inlining.
上一篇: 使用可变参数模板的更多依赖类型
下一篇: c ++模板类成员函数专业化