为什么在这种情况下不是constexpr?

时间:2019-02-22 12:59:04

标签: c++ string compiler-errors constexpr

我有一个笨拙的strexp版本的strlen,在某些情况下编译器接受它为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;
}

为什么在make_string函数中将constexpr_strlen视为constexpr,而不是?

对于我在这里看到的内容,它可以在编译时进行计算,不是吗?

1 个答案:

答案 0 :(得分:3)

主要问题是,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

因此非常简单:constexpr函数的结果也是constexpr if ,并且仅当 all 参数为函数时会被constexpr本身调用(只有那时,该函数才在编译时评估),否则它将是一个运行时值(并且该函数在运行时评估)。

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

(当然,constexpr甚至不是constexpr,但是如果constexpr函数的参数不能假设 $('select.chosen-result option:contains("Swatch 1")').hide(); $('select.chosen-result').trigger("chosen:updated"); ,则普通函数参数的假设甚至更少。 )