作为练习我试图使用模板编写数组实现,但使用函数指针作为模板参数.每次对数组进行索引时都会调用此函数.
template<typename T,int size> using Array_fnIndex = void (*)(int index); template<typename T,int size,typename Array_fnIndex<T,size> fnIndex> struct Array { T data[size]; T& operator[](int index) { fnIndex(index); return data[index]; } }; // example index function template<typename T,int size> void checkIndex(int index) { assert(index < size); } int main() { Array<int,10,checkIndex<int,10>> a; // this works Array<int,11>> b; // this also works,not what I want Array<int,checkIndex> c; // this doesn't work,but what I want return 0; }
main函数中的最后一个Array声明是我想要的,其中checkIndex的模板参数与Array中的先前模板参数匹配.但是这不能编译(使用Microsoft编译器).我收到以下错误:
error C2440: 'specialization': cannot convert from 'void (__cdecl *)(uint)' to 'void (__cdecl *)(uint)' note: None of the functions with this name in scope match the target type
有没有办法获得所需的结果,其中提供的函数的模板参数从其他参数推断?
解决方法
可能不适用于您的实际用例,但我建议一个包含执行检查的函数的可调用对象:
template<typename T,typename fnIndex> struct Array { T data[size]; T& operator[](int index) { fnIndex{}.template check<size>(index); return data[index]; } }; struct checkIndex { template<int size> void check(int index) { assert(index < size); } }; int main() { Array<int,checkIndex> c; return 0; }
让我们分析fnIndex {}.模板检查< size>(索引):
fnIndex{} // make a temporary object of type `fnIndex` .template check<size>(index) // call its `check` method using `size` // as a template argument and `index` as // as a function argument
.template消歧语法是必需的,因为编译器不知道检查的含义 – 它可能是一个字段,并且该行可以解释为:
fnIndex {}.检查<尺寸> (指数)
在哪里<是小于运算符,>是大于运算符,(索引)是表达式.