为什么表达式strlen(cstr1)没有求值为常量,其中cstr1是一个const char数组?

时间:2015-09-24 08:07:48

标签: c++ const constexpr

编译器说当我构建以下代码时,表达式没有计算为常量。但我不知道如何修复错误。有人可以帮忙吗?

#include <iostream>
#include <cstring>

const char cstr1[] = "Hello";
const char cstr2[] = "world!";

int main()
{
    constexpr size_t new_size = strlen(cstr1) + strlen(" ") + strlen(cstr2) + 1;
    char cstr3[new_size];

    strcpy(cstr3, cstr1);
    strcat(cstr3, " ");
    strcat(cstr3, cstr2);

    std::cout << cstr3 << std::endl;
}

3 个答案:

答案 0 :(得分:2)

它不起作用,因为strlen未声明为constexpr,因此其结果无法在constexpr中使用。

你可以尝试使用sizeof解决这个问题,但实际上你不应该首先使用C风格的字符串。 C ++有std::string的原因是:

const std::string str1 = "Hello";
const std::string str2 = "world!";

int main(){
    std::string str3 = str1 + ' ' + str2;

    std::cout << str3 << std::endl;
}

答案 1 :(得分:1)

标准说strlen是一个真正的函数,并且编译器不知道它的作用,它不是constexpr类型的函数(毕竟,如果您使用fgets从文件或终端读取输入,则调用的函数完全相同。

许多现代编译器都了解strlen的作用,因此编译器将优化对函数的调用,并在此类情况下将其替换为常量。但是,它不需要在标准中以这种方式运行,因此它是否在特定编译器中工作完全取决于特定的编译器(以及可能的编译器选项,以实现某种类型的优化!)

答案 2 :(得分:0)

strlen()是一个在运行时评估的函数,而不是编译时。因此错误消息。它继承自C,因此未声明constexpr(特定于更高版本的C ++)。

最好避免使用<cstring> - 和char数组 - 并使用std::string

中声明的<string>类型
#include <iostream>
#include <string>

const std::string cstr1 = "Hello";
const std::string cstr2 = "world!";

int main()
{
    std::string cstr3 = cstr1 + std::string(" ") + cstr2;
    std::cout << cstr3 << std::endl;
}