constexpr const char * vs constexpr const char []

时间:2015-11-13 12:34:52

标签: c++ c++11 constexpr

“第一次尝试”不会在第二次尝试时编译。为什么?有什么区别?

首次尝试:

#include <iostream>

int main()
{
    constexpr const char text2[] = "hello";
    constexpr const char * b = &text2[4];  // error: '& text2[4]' is not a constant expression
    std::cout << b << std::endl;
}

第二次尝试:

#include <iostream>
int main()
{
constexpr const char * text1 = "hello";
constexpr const char * a = &text1[4];
std::cout << a << std::endl;

return 0;
}

我用(g ++版本4.9.2)编译

g++ -std=c++11 -o main *.cpp

给出以下错误

main.cpp: In function 'int main()':
main.cpp:7:40: error: '& text2[4]' is not a constant expression constexpr const char * b = &text2[4];  // error: '& text2[4]' is not a constant expression  

1 个答案:

答案 0 :(得分:22)

从草案C ++ 11标准部分5.19 [expr.const] 我们可以看到address constant expression是(强调我的锣前锋):

  

[...] prvalue核心常量表达式   指针类型,用于计算对象的地址   静态存储持续时间,到函数的地址,或为null   指针值,或类型的prvalue核心常量表达式   的std :: nullptr_t。

在第一种情况下,虽然"hello"是一个具有静态存储持续时间的字符串文字。它被复制到一个没有静态存储持续时间的数组text2

在第二种情况下,text1是指向具有静态存储持续时间的string literal的指针。

更改第一个示例以使text2成为静态( see it live ):

constexpr char static text2[] = "hello";
               ^^^^^^

我们不再收到错误。

我们可以看到字符串文字具有来自2.14.5 [lex.string] 部分的静态存储持续时间:

  

也引用普通的字符串文字和UTF-8字符串文字   作为窄字符串文字。窄字符串文字的类型为“数组”   of n const char“,其中n是下面定义的字符串的大小,   并具有静态存储时间(3.7)。