考虑这段代码:
int x = 0;
template<int& I>
struct SR {};
template<int* I>
struct SP {};
SR<(x)> sr;
SP<&(x)> sp;
int main(void)
{
}
clang++ 3.8.0 提示:
main.cpp:10:5: error: non-type template argument does not refer to any declaration
SP<&(x)> sp;
^~~
main.cpp:6:15: note: template parameter is declared here
template<int* I>
^
g++ 6.1.0 提示:
main.cpp:10:8: error: template argument 1 is invalid
SP<&(x)> sp;
^
当然,如果我删除括号,一切正常,如 SP<&x> sp;
.但是我在 C++14 标准中找不到任何会在这里有所作为的内容。此外,为什么引用案例没问题但指针案例不好?编译器拒绝该程序是否正确?
最佳答案
我对该标准的理解是它应该被允许,但我想 GCC 和 Clang 的实现者不同意我的解释,他们可能是正确的。要获得明确的答案,询问 std-discussion@isocpp.org 邮件列表可能是个好主意(我会给他们发一封电子邮件)。措辞可能有缺陷。
根据 [temp.arg.nontype],非类型模板参数的一种可能形式是:
... a constant expression (5.19) that designates the address of a complete object with static storage duration and external or internal linkage or a function with external or internal linkage, including function templates and function template-ids but excluding non-static class members, expressed (ignoring parentheses) as
&
id-expression, where the id-expression is the name of an object or function, except that the&
may be omitted if the name refers to a function or array and shall be omitted if the corresponding template-parameter is a reference ...
这一切都取决于“忽略括号”的含义。 GCC 和 Clang 都接受 (&x)
但不接受 &(x)
;他们似乎已经决定“忽略括号”仅意味着在外部,而不是在 id 表达式周围。如果这是标准委员会的意图,则应该澄清语言。
编辑:在C++17 draft ,这是明确允许的,因为允许的非类型模板参数的形式已大大放宽:
A template-argument for a non-type template-parameter shall be a converted constant expression ([expr.const]) of the type of the template-parameter. For a non-type template-parameter of reference or pointer type, the value of the constant expression shall not refer to (or for a pointer type, shall not be the address of):
- a subobject ([intro.object]),
- a temporary object ([class.temporary]),
- a string literal ([lex.string]),
- the result of a
typeid
expression ([expr.typeid]), or- a predefined
__func__
variable ([dcl.fct.def.general]).
关于c++ - 括号是否会使指针模板参数无效?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39777331/