C++模板参数推理
C++ template parameter inference
作为练习,我尝试使用模板编写数组实现,但使用函数指针作为模板参数。每次为数组编制索引时都会调用此函数。
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, 10, checkIndex<int, 11>> b; // this also works, not what I want
Array<int, 10, checkIndex> c; // this doesn't work, but what I want
return 0;
}
main
函数中的最后一个数组声明是我想要的,其中 checkIndex 的模板参数与数组中以前的模板参数匹配。但是这不会编译(使用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, int size, 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, 10, checkIndex> c;
return 0;
}
魔杖盒示例
我们来分析一下fnIndex{}.template check<size>(index)
:
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
消除歧义语法是必需的,因为编译器不知道check
的含义 - 它可能是一个字段,该行可以解释为:
fnIndex{}.check < size > (index)
其中<
是小于运算符,>
是大于运算符,(index)
是表达式。
使用 .template
告诉编译器我们要调用模板方法。
相关文章:
- 如何反转整数参数包
- 使用C++库在Android项目中修改gradle中的cmake参数,用于插入指令的测试
- 如何使用默认参数等选择模板专业化
- 模板参数替换失败,并且未完成隐式转换
- 具有默认模板参数的多态类的模板推导失败
- lambda参数转换为constexpr技巧,然后获取带链接的数组
- 将数组作为参数传递给函数安全吗?作为第三方职能部门,可以探索他们想要的之外的其他元素
- 函数调用中参数的顺序重要吗
- 部分定义/别名模板模板参数
- 模板-模板参数推导:三个不同的编译器三种不同的行为
- 使用不带参数的函数访问结构元素
- 基于另一个成员参数将函数调用从类传递给它的一个成员
- 如何在OMNET++中指定与命令行参数组合的输出文件名
- 如何使用Luacneneneba API正确读取字符串和表参数
- 在派生函数中指定void*参数
- 关于模板参数推理的看似有缺陷的段落?
- 从函数指针对标准 C++98 中的函数类型参数进行静态推理
- C++模板参数推理
- 使用构造函数进行类模板参数推理
- 为什么此模板参数推理失败