[英]Why using 0 as default non type template parameter for void* is not allowed
Why does the following code fail to compile? 为什么以下代码无法编译? Even though it is legal to do
void* ptr = 0;
尽管做
void* ptr = 0;
是合法的void* ptr = 0;
template <void* ptr = 0>
void func();
int main() {
func();
return 0;
}
I ask because I found that a very trusted source did something similar and it failed to compile on my machine 我问,因为我发现一个非常受信任的来源做了类似的事情,但它无法在我的机器上编译
NOTE Should have posted the compiler error along with my question so here it is 注意应该已经发布编译器错误以及我的问题所以这里是
so_test.cpp:1:23: error: null non-type template argument must be cast to template parameter type 'void *'
template <void* ptr = 0>
^
static_cast<void *>( )
so_test.cpp:1:17: note: template parameter is declared here
template <void* ptr = 0>
^
so_test.cpp:5:5: error: no matching function for call to 'func'
func();
^~~~
so_test.cpp:2:6: note: candidate template ignored: substitution failure [with ptr = nullptr]: null non-type template argument must be cast to template parameter type 'void *'
void func();
^
Template parameters of type void*
are not allowed. 不允许使用
void*
类型的模板参数。 See [temp.param]/4 in the standard, also summarized at http://en.cppreference.com/w/cpp/language/template_parameters#Non-type_template_parameter 请参阅标准中的[temp.param] / 4,也可在http://en.cppreference.com/w/cpp/language/template_parameters#Non-type_template_parameter中进行总结。
A non-type template-parameter shall have one of the following (optionally cv-qualified ) types:
非类型模板参数应具有以下之一(可选的cv限定 )类型:
- integral or enumeration type,
积分或枚举类型,
- pointer to object or pointer to function,
指向对象或指向函数的指针,
- lvalue reference to object or lvalue reference to function,
左值引用对象或左值引用函数,
- pointer to member,
指向成员的指针,
std::nullptr_t
.std::nullptr_t
。
Since void
is not an object or function type, void*
is not among the permitted types. 由于
void
不是对象或函数类型,因此void*
不属于允许的类型。
Addendum: A void*
value known at compile time wouldn't be very useful. 附录:编译时已知的
void*
值不是很有用。 It's not possible to examine its value at compile time since reinterpret_cast
is not allowed in constant expressions; 由于在常量表达式中不允许使用
reinterpret_cast
因此无法在编译时检查其值; nor is it possible to convert it to T*
for some object type T
at compile time. 也不可能在编译时将它转换为某些对象类型
T
T*
。
You tried to initialize a pointer with an int
. 您尝试使用
int
初始化指针。 Many implicit conversions, including integer-to-pointer conversions, don't happen in non-type template parameters. 许多隐式转换(包括整数到指针转换)不会发生在非类型模板参数中。
The cppreference summary of the behaviour in C++14 for non-template parameters of pointer to object type is: 对于指向对象类型的指针的非模板参数,C ++ 14中行为的cppreference摘要是:
For pointers to objects, the template arguments have to designate the address of an object with static storage duration and a linkage (either internal or external), or a constant expression that evaluates to the appropriate null pointer or std::nullptr_t value.
对于指向对象的指针,模板参数必须指定具有静态存储持续时间和链接(内部或外部)的对象的地址,或者计算为适当的空指针或std :: nullptr_t值的常量表达式。
So the code could be: 所以代码可以是:
template <void* ptr = nullptr>
void f();
Footnote: it seems unclear whether void *
is allowed as a parameter type, but compilers accept the above code. 脚注:似乎不清楚
void *
是否允许作为参数类型,但编译器接受上述代码。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.