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]
static_assert
. Else, you could invoke instantiation of a second template (independent ofIdxIterator
) insideinc
that does this check. – dyptemplate<unsigned var> void foo() { /*impl*/ }
– Joseph Franciscus