c++ - 为什么在这种情况下它不是 constexpr ?

标签 c++ string compiler-errors constexpr

我有一个 strlen 的愚蠢 constexpr 版本,编译器在某些情况下将其接受为 constexpr,但在其他情况下则不然,这是一个示例:

template <std::size_t MAX_SIZE>
class FixedString
{
public:
    explicit FixedString(const char* str)
    {
        for(std::size_t i = 0; i < MAX_SIZE; i++)
        {
            data[i] = str[i];
        }
    }

    char data[MAX_SIZE];
};

constexpr std::size_t constexpr_strlen(const char *str)
{
    for(std::size_t i = 0; i < std::numeric_limits<std::size_t>::max(); i++)
    {
        if(str[i] == '\0')
        {
            return i;
        }
    }

    return 0;
}

// doesn't compile, compiler says non-type template argument is not a constant expression
auto make_string(const char* str)
{
    return FixedString<constexpr_strlen(str)>(str);
}

int main()
{
    constexpr bool IS_DEV = true;

    // works fine
    std::array<int, constexpr_strlen(IS_DEV ? "Development" : "Production")> arr;

    // works fine
    FixedString<constexpr_strlen(IS_DEV ? "Development" : "Production")> str("Develop");

    // doesn't compile, compiler says variable has incomplete type 'void'
    auto string = make_string("Not working");

    return 1;
}

为什么 constexpr_strlen 在 make_string 函数中被认为是 constexpr,而在 make_string 函数中却不是?

就我在这里看到的,它可以在编译时计算,不是吗?

最佳答案

主要问题是,constexpr 函数根据定义可以在编译时以及运行时调用。让我们从一个更简单的例子开始:

constexpr int f(int n) { return n };

int n = 7;

// n could be modified!

f(n); // compiler cannot know which value n has at runtime,
      // so the function needs to be executed at runtime as well!

f(7); // well, now right the opposite...

所以这很简单:constexpr 函数的结果也是 constexprif 并且仅当all 调用函数的参数是 constexpr 本身(只有这样,该函数才会在编译时求值),否则,它将是一个运行时值(并且该函数在运行时求值) -时间)。

constexpr 函数内部,编译器无法知道该函数是否仅使用 constexpr 参数调用;因此函数参数总是需要被视为非constexpr。我们在这里...

(当然,make_string 甚至不是 constexpr,但是如果 constexpr 不能被假定为 constexpr 的参数> 函数,那么普通函数参数就更少了...)

关于c++ - 为什么在这种情况下它不是 constexpr ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54827732/

相关文章:

C++错误: default template arguments may not be used in function template

c++ - 使用 C 或 C++(或 Ada 95)进行 Windows LDAP 组用户检查

python - 将其中包含非 ASCII 符号的 Unicode 对象转换为字符串对象(在 Python 中)

javascript - 如何在 js 中拆分字符串,但有一些异常(exception)

r - '['正确地执行了什么操作?

compilation - genbarcode 0.4-make : *** [.dep] Error 123

c++ - 使用 g++ 编译器出现奇怪的错误

C++ Switch 语句大小写错误

c++ - 为什么以及如何从接口(interface)定义语言 (IDL) 生成头文件

c++ - 在 C++ 中打印完整的回溯