圆括号是否使指针模板参数无效?

考虑这个代码:

int x = 0;

template<int& I>
struct SR {};

template<int* I>
struct SP {};

SR<(x)> sr;
SP<&(x)> sp;

int main(void)
{
}

铿锵声++ 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 Standard中找到任何可以在这里发挥作用的东西。 此外,为什么参考案例好,但指针案件不好? 编译器是否正确拒绝该程序?


我对标准的阅读是应该允许的,但我认为GCC和Clang的实现者不同意我的解释,他们可能是正确的。 为了得到明确的答案,最好问问std-discussion@isocpp.org邮件列表(我会给他们发一封电子邮件)。 措辞可能是一个缺陷。

根据[temp.arg.nontype],非类型模板参数的可能形式之一是:

...一个常量表达式(5.19),指定具有静态存储持续时间和外部或内部链接的完整对象的地址,或者具有外部或内部链接的函数,包括函数模板和函数模板id,但不包括非静态类成员表示(忽略括号内)作为& ID表达,其中的ID-expression是对象或函数的名称,除了&如果名称是指功能或阵列,并且如果相应的模板将被省略,可以省略 - 参数是一个参考...

这一切都取决于“忽略括号”的含义。 GCC和Clang都接受(&x)但不接受&(x) ; 他们似乎已经决定“忽略括号”仅仅意味着在外面,而不是围绕id表达。 如果这是标准委员会的意图,则应该澄清该语言。

编辑:在C ++ 17草案中,这是明确允许的,因为可允许的非类型模板参数的形式已大大放宽:

非类型模板参数的模板参数应该是模板参数类型的转换常量表达式([expr.const])。 对于引用或指针类型的非类型模板参数,常量表达式的值不应引用(或者对于指针类型,不应该是地址):

  • 一个子对象([intro.object]),
  • 临时对象([class.temporary]),
  • 一个字符串文字([lex.string]),
  • typeid表达式的结果([expr.typeid])或
  • 一个预定义的__func__变量([dcl.fct.def.general])。
  • 链接地址: http://www.djcxy.com/p/93397.html

    上一篇: Do parentheses make a pointer template argument invalid?

    下一篇: Slow rendering of template using angular2 *ngFor