decltype(“Hello”)的结果是什么?

时间:2013-02-24 00:17:49

标签: c++ c++11 string-literals decltype

我从以下所有编译器中得到了意想不到的结果(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!"
        );
}

我原本希望而不是上面的编译时断言能够触发,但确实如此。毕竟,这个没有(如预期的那样):

#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!"
        );
}

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

1 个答案:

答案 0 :(得分: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的类型。

由于 string literals are lvalues ,根据上述段落和附件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!"
        );
}

最后,即使hello变量 也是左值,问题文本中的第二个编译时断言也不会触发,因为hello notarenthesized id-expression ,这使它落入第7.1.6.2/4段中上述列表的第一项。因此,decltype(hello)的结果是hello命名的实体的类型,即char const[6]