c ++模板类成员函数专业化
我有一个问题,我想在下面的代码中专门化模板类的模板成员函数。 这个问题的答案显式专门化模板类成员函数似乎表明它不能完成。 这是否正确,如果有的话,是否有任何解决方法可以使用,以便通过内联inc函数在编译时扩展?
非常感谢!
#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 ++吐出:
test2.cpp:32:13:错误:在非命名空间范围'struct IdxIterator'test2.cpp:32:25中显式专门化:错误:在非命名空间范围'struct IdxIterator'test2.cpp:33:23:在成员函数'void IdxIterator :: inc()[int dim = -0x000000000000003fe,IT = int *,unsigned int N = 1u')中错误:template-id'inc <-0x00000000000000001>' ]':test2.cpp:27:9:error:模板实例化深度超过1024的最大值(使用-ftemplate-depth =增加最大值)实例化'void IdxIterator :: inc()[with int dim = -0x000000000000003ff,IT = int *,unsigned int N = 1u]'test2.cpp:27:9:从'void IdxIterator :: inc()[int int = 0x00000000000000001,IT = int *,unsigned int N = 1u]'递归实例化'' test2.cpp:27:9:从'IdxIterator :: inc()[int dim = 0,IT = int *,unsigned int N = 1u]'实例化'test2.cpp:41:5:从'IdxIterator IdxIterator :: operator ++()[with IT = int *,unsigned int N = 1u]'test2.cpp:53:5:从这里实例化
test2.cpp:在全局作用域:test2.cpp:22:15:warning:内联函数'void IdxIterator :: inc()[使用int dim = -0x000000000000003ff,IT = int *,unsigned int N = 1u]',但是从未定义[默认启用]
在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>()); };
};
您可以执行编译器错误消息的建议:
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;
}
即将定义移动到名称空间范围。
在类之外创建一个辅助结构体
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*/);
}
};
请注意,如果您使用的是GCC,您可以__attribute__((always_inline))
强制内联。