constexpr函数返回字符串字面值

9
一个返回整数字面值副本的函数。
int number()
{ return 1; }

使用关键字constexpr可以轻松将其转换为普通的编译时表达式。

constexpr int number()
{ return 1; }

然而,当涉及到字符串字面值时,我开始感到困惑。通常的方法是返回一个指向字符串字面值的const char类型指针。

const char* hello()
{ return "hello world"; }

但我认为仅仅将 "const" 改为 constexpr 并不是我想要的(作为奖励,它还会在使用 gcc 4.7.1 时产生编译器警告 deprecated conversion from string constant to 'char*'

constexpr char* hello()
{ return "hello world"; }

有没有一种方法可以实现hello(),使得在下面的示例中,调用被替换为常量表达式?
int main()
{
    std::cout << hello() << "\n";
    return 0;
}
2个回答

13

constconstexpr不可互换的,在你的情况下,你不想去掉 const,但是你想这样添加 constexpr

constexpr const char* hello()
{
  return "hello world";
}

您在取消使用const时收到的警告是因为字符串字面值是一个n个const char的数组,所以指向字符串字面值的指针应该是*const char **,但在C中,字符串字面值是char数组,即使尝试修改它们是未定义行为,但为了向后兼容而保留了它们,但已被淘汰,因此应该避免使用。

有道理,谢谢。那么constexpr数组呢?在constexpr const char* ptrToLiteral = "hello";constexpr char cstring[] = "hello";之间,在底层有什么区别吗?如果有的话,是什么?后者以不同的方式存储吗? - jms
@user1062874 是的,第二种情况 cstring 是一个可修改的数组,它将被初始化为字符串字面值 "hello" 的副本,而第一种情况 ptrToLiteral 只是指向一个字符串字面值。 - Shafik Yaghmour
我感到困惑,需要注意的是在原始注释中 cstring 被定义为 constexpr,因此它不应该被修改,试图像 cstring[0] = 'a'; 这样修改 cstring 预期会导致错误 _assignment of read-only location 'cstring[0]'_。 - jms
1
@user1062874 词汇选择不太恰当,因为在这种情况下 cstring 不可修改,因为它是一个 constexpr,但在其他情况下则可以修改。 - Shafik Yaghmour
我认为这个问题最好单独提出来:https://dev59.com/3GEh5IYBdhLWcg3wVCAb - jms

2

强制constexpr求值:

constexpr const char * hi = hello();
std::cout << hi << std::endl;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接