C++ 为什么void*作为模板参数用作函数参数而不是模板参数?
我有两个版本的C++ 为什么void*作为模板参数用作函数参数而不是模板参数?,c++,templates,c++11,C++,Templates,C++11,我有两个版本的我的\u begin: template<typename T, typename std::enable_if<std::is_array<T>::value>::type* = 0> typename std::decay<T>::type my_begin(T& array) { return array; } 错误: main.cpp:17:30: note: template argument dedu
我的\u begin
:
template<typename T, typename std::enable_if<std::is_array<T>::value>::type* = 0>
typename std::decay<T>::type my_begin(T& array) {
return array;
}
错误:
main.cpp:17:30: note: template argument deduction/substitution failed:
main.cpp:16:80: error: could not convert template argument '0' to 'std::enable_if<true, void>::type* {aka void*}'
template<typename T, typename std::enable_if<std::is_array<T>::value>::type* = 0>
main.cpp:17:30:注意:模板参数扣除/替换失败:
main.cpp:16:80:错误:无法将模板参数“0”转换为“std::enable_if::type*{aka void*}”
模板
但第二种方法有效。当我将第一个中的0更改为NULL ptr时,它也可以工作(但仍然不适用于NULL)。我知道在模板中它需要显式转换(在这种情况下,从int
到void*
),但为什么第二个不需要它呢
另一个问题是,如果我删除
*
和=
之间的空格,它也会失败。为什么呢?§14.1[temp.param]/p4说:
非类型模板参数应具有以下之一:
(可选cv限定)类型:
- 整型或枚举型
- 指向对象的指针或指向函数的指针
- 对对象的左值引用或对函数的左值引用
- 指向成员的指针
std::nullptr\u t
void*
模板参数。void*
是一种对象指针类型,但不是指向对象类型的指针(§3.9.2[basic.component]/p3):
指向void
的指针或指向对象类型的指针的类型为
调用对象指针类型。[注意:指向void
的指针
但是,没有指向对象类型的指针,因为void
不是
对象类型。-结束注释]
如果我们假设这是一个缺陷,并且该标准真正的意思是说“对象指针类型”,那么§14.3.2[临时参数非类型]/p5仍然不允许使用0
和company(增加强调):
对用作表达式的每个表达式执行以下转换
非类型模板参数。如果无法使用非类型模板参数
转换为相应模板参数的类型,然后
程序格式不正确
- [……]
- 对于类型为pointer to object、限定转换(4.4)和数组到指针转换的非类型模板参数
(4.2);如果模板参数的类型为
, 应用空指针转换(4.10)。[注意:尤其是, 零值整型文字的null指针转换 (4.10)也不适用从衍生到基础的转换(4.10)。尽管 0是的非类型模板参数的有效模板参数 整型,它不是非类型的有效模板参数 指针类型的模板参数。但是,std::nullptr\u t
和(int*)0
是类型为的非类型模板参数的有效模板参数 “指向整数的指针”-结束注释]nullptr
=0
适用于函数默认参数,因为这些参数受正常转换规则的约束,该规则允许值为0的整数文本转换为空指针,而不是模板参数的特殊规则
如果我删除*和=,它也会失败。为什么
最大munch。如果删除了空格,
*=
是单个标记(复合赋值运算符)。就像在C++03中,您必须在std::vector
中的
之间放置空格一样,感谢您的详细回答!
int a[10];
int* a_it = my_begin(a);
main.cpp:17:30: note: template argument deduction/substitution failed:
main.cpp:16:80: error: could not convert template argument '0' to 'std::enable_if<true, void>::type* {aka void*}'
template<typename T, typename std::enable_if<std::is_array<T>::value>::type* = 0>