以下内容无法编译:
template<void *p>
class X {
// ...
};
int r;
int main()
{
X<&r> x;
return 0;
}
错误消息是
x.cc:10:6:错误:无法将模板参数'&r'转换为'void *'
显式地转换&r到(void *)也无济于事 . 错误消息变为:
x.cc:10:14:错误:无法将模板参数'(void *)(&r)'转换为'void *'
标准的哪一部分指明了这种行为? GCC版本是 gcc version 5.2.1 20151003 (Ubuntu 5.2.1-21ubuntu2)
Edit:
请注意使用例如int *而不是void *按预期工作 .
Edit: (answering myself)
当指定-std = c 1z时, not 与 gcc HEAD 6.0.0 20151016 (experimental) 一起工作,既没有隐式也没有显式转换为"void *" .
它 does 与 clang HEAD 3.8.0 (trunk 250513) 一起工作,并且自从(至少) clang 3.6.0 (tags/RELEASE_360/final) 指定--std = c 1z并明确地转换为* void *“时 . 在没有显式强制转换的情况下,clang抱怨如下:
x.cc:10:7:错误:转换后的常量表达式中不允许从'int *'转换为'void *'
负责修复c语言规范中的这个bug是N4268,clang已经实现了 .
2 回答
通常,任何指向
void*
的指针都允许转换 .但是,对于非类型模板参数,指定了某些转换:
由于省略,我们可以推断这种转换是不允许的 .
我不能引用你的章节和经文来引起我的兴趣(编辑是受欢迎的),但你想要做的是不允许在c .
必须在编译时知道模板参数 . 指针仅在链接时解析,除非:
在模板参数列表中使用
= nullptr
默认它们 .它们是成员函数指针(在编译时是已知的,因为它们仅仅是偏移量) .
例如,这将编译: