所以我对这是如何工作感到困惑。给出:
template <typename T>
int foo(T t) { t.foo(); }
似乎此调用应该失败:
decltype(foo(int{ 13 })) fail = 42;
cout << fail << endl;
取而代之的是it just prints:
42
它可以在我有权访问的所有编译器上运行。这是正确的行为吗?我要求C ++标准引用。
答案 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
中的表达式由标准定义为不被评估,它们仅被解析以获取表达式的类型。