decltype("Hello")的结果是什么?

And*_*owl 36 c++ decltype string-literals c++11

我从我尝试过的所有编译器中得到了意想不到的结果(GCC 4.7.2,GCC 4.8.0 beta,ICC 13.0.1,Clang 3.2,VC10):

#include <type_traits>

int main()
{
    // This will fire
    static_assert(
        std::is_same<decltype("Hello"), char const[6]>::value, 
        "Error!"
        );
}
Run Code Online (Sandbox Code Playgroud)

我原本以为上面的编译时断言不会触发,但确实如此.毕竟,这个没有(如预期的那样):

#include <type_traits>

int main()
{
    char const hello[6] = "Hello";

    // This will not fire
    static_assert(
        std::is_same<decltype(hello), char const[6]>::value, 
        "Error!"
        );
}
Run Code Online (Sandbox Code Playgroud)

那么decltype("Hello")根据C++ 11标准的结果是什么(参考文献受到高度赞赏)?我应该将它与什么进行比较,以便上面的编译时断言不会触发?

And*_*owl 30

[ 注意:最初,这并不是一个自我回答的问题; 在我描述我的调查尝试时,我碰巧找到了自己的答案,我认为分享它会很好.]

根据C++ 11标准的附录C(2.14.5):

字符串文字的类型从"char of char"更改为" const char数组 ".[....]

此外,第7.1.6.2/4段规定(关于结果decltype):

表示的类型decltype(e)定义如下:

- 如果e是未加密码的id-expression或未加括号的类成员访问(5.2.5),decltype(e)则是由名为的实体的类型e.如果没有这样的实体,或者e命名一组重载函数,程序就会形成错误;

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

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

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

由于字符串文字是左值,根据上面的段落和附件C中的段落,结果decltype("Hello")是对大小为6的常数窄字符数组的左值引用:

#include <type_traits>

int main()
{
    // This will NOT fire
    static_assert(
        std::is_same<decltype("Hello"), char const (&)[6]>::value, 
        "Error!"
        );
}
Run Code Online (Sandbox Code Playgroud)

最后,即使hello变量也是一个左值,从问题的案文不火的第二编译时断言,因为hello加括号的ID表达,这使得它落入上述列表的第一个项目从第7.1.6.2/4.因此,结果decltype(hello)是名为by的实体的类型hello,即char const[6].

  • 对问题和答案都+1.我保证我再也不会碰到C++编译器了. (3认同)
  • @Valloric:我从所有编译器得到的结果是相同的,它们是正确的*:断言触发.我只是抱着错误的期望,因为我期待断言不要开火.这就是我所说的"意外结果".答案应该清除它. (2认同)