apr*_*ori 10 c++ standards gcc templates void
以下内容无法编译:
template<void *p>
class X {
// ...
};
int r;
int main()
{
X<&r> x;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
错误消息是
x.cc:10:6:错误:无法将模板参数'&r'转换为'void*'
显式地转换&r到(void*)也无济于事.错误消息变为:
x.cc:10:14:错误:无法将模板参数'(void*)(&r)'转换为'void*'
标准的哪一部分指明了这种行为?GCC版本是gcc版本5.2.1 20151003(Ubuntu 5.2.1-21ubuntu2)
编辑:
请注意,使用例如int*而不是void*按预期工作.
编辑:(回答自己)
它并不能一起工作的gcc HEAD 6.0.0 20151016(实验)指定-std = C++ 1Z,既不与隐式也不与显式转换到"无效*"时.
它确实与clang HEAD 3.8.0(主干250513)一起使用,并且在指定--std = c ++ 1z并显式转换为*void*时已经(至少)clang 3.6.0(标记/ RELEASE_360/final)没有明确的演员,clang抱怨如下:
x.cc:10:7:错误:在转换的常量表达式中不允许从'int*'转换为'void*'
负责修复c ++语言规范中的这个bug的是N4268,它已经实现了.
我无法直接引用您的章节和诗句(欢迎编辑),但您尝试做的事情在 C++ 中是不允许的。
模板参数必须在编译时已知。指针仅在链接时解析,除非:
它们默认= nullptr在模板参数列表中使用。
它们是成员函数指针(在编译时已知,因为它们只是偏移量)。
例如,这将编译:
template<void * = nullptr>
class X {
// ...
};
int r;
int main()
{
X<nullptr> x;
return 0;
}
Run Code Online (Sandbox Code Playgroud)