不应该decltype触发器编译其参数?

Jon*_*Mee 16 c++ templates compilation decltype language-lawyer

所以我很困惑这是如何工作的.鉴于:

template <typename T>
int foo(T t) { t.foo(); }
Run Code Online (Sandbox Code Playgroud)

似乎这个调用应该失败:

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

cout << fail << endl;
Run Code Online (Sandbox Code Playgroud)

相反它只是打印:

42

它以我可访问的所有编译器的方式工作.这是正确的行为吗?我请求C++标准的引用.

Som*_*ken 17

[dcl.spec]中:

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

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

否则,如果e是未加密的id-expression或未加密的类成员访问([expr.ref]),则decltype(e)是e命名的实体的类型.如果没有这样的实体,或者如果e命名了一组重载函数,那么该程序就会形成错误;

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

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

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

decltype说明符的操作数是未评估的操作数 (Clause [expr]).

(强调我的)

所以你foo(int{ 13 })永远不会被评估.

  • 如果将上述函数模板的定义更改为`template <typename T> auto foo(T t){t.foo(); 但是,模板的实例化似乎发生了 - 这对我来说很有意义,因为没有返回类型推导,"decltype"就没有办法产生任何东西.当然,这以编译时错误结束.在上面的条款中,这种行为反映在哪里?我错过了什么吗? (4认同)
  • @thokra [decl.spec.auto]:_"当实例化定义时,即使函数体包含带有非类型相关操作数的return语句,也会在其声明类型中使用占位符的函数模板返回类型推导. [注意:因此,任何使用函数模板的特化都会导致隐式实例化.]"_ (2认同)

Jes*_*uhl 5

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

  • 这是一个简短的答案.我将对它做出评论,这比答案本身还要长:我已经确定我可以访问的编译器支持你的陈述.所以问题是:"这是正确的行为吗?" 要确定你需要引用的东西超过你获得的知识. (6认同)
  • 提到宇宙主文件的强制性问题. (5认同)
  • http://eel.is/c++draft/dcl.type.simple#4 _ decltype说明符的操作数是未评估的操作数(Clause [expr])._ (3认同)
  • @GillBates你完美地总结了这个网站 (2认同)