难道不应该触发其参数的触发器编译吗?

时间:2016-07-14 12:05:49

标签: c++ templates compilation language-lawyer decltype

所以我对这是如何工作感到困惑。给出:

template <typename T>
int foo(T t) { t.foo(); }

似乎此调用应该失败:

decltype(foo(int{ 13 })) fail = 42;

cout << fail << endl;

取而代之的是it just prints

  

42

它可以在我有权访问的所有编译器上运行。这是正确的行为吗?我要求C ++标准引用。

2 个答案:

答案 0 :(得分:17)

[dcl.spec]中:

  

对于表达式e,由decltype(e)表示的类型定义为   如下:

     

如果e是未标记的id-expression,则命名从分解的标识符列表引入的左值或引用   声明,decltype(e)是在中给出的引用类型   分解声明的规范([dcl.decomp]);

     

否则,如果e是未加密码的id-expression或未加括号的类成员访问([expr.ref]),则decltype(e)是   由e命名的实体的类型。如果没有这样的实体,或者如果e   命名一组重载函数,程序格式不正确;

     

否则,如果e是x值,则decltype(e)是T&amp;&amp;,其中T是e的类型;

     

否则,如果e是左值,则decltype(e)是T&amp;,其中T是e的类型;

     

否则,decltype(e)是e的类型。

     

decltype说明符的操作数是未评估的操作数   (条款[expr])。

(强调我的)

因此,您的// | non-parenthesis // | | or // | | | not preceded by parenthesis // | | | | actual parenthesis // | | | | | not followed by parenthesis // | | | | | | 1+ length(adjust with desired quantifier) test.matches("([^(]|(?<!\\()\\((?!=\\())+") 永远不会被评估。

答案 1 :(得分:5)

decltype中的表达式由标准定义为不被评估,它们仅被解析以获取表达式的类型。