constexpr,或者不是 constexpr,这是个问题

Kar*_*yan 1 c++ constexpr c++20

constexpr在 C++中玩弄并注意到我希望理解的奇怪行为。考虑来自标准 5.19 部分的这段代码。

constexpr int f1(int k) {
    constexpr int x = k; // error: x is not initialized by a
                         // constant expression because lifetime of k
                         // began outside the initializer of x
    return x;
}
Run Code Online (Sandbox Code Playgroud)

作为错误状态,生命周期k在 的初始值设定项之外开始x,因此我们不能确定这x 将是一个常量表达式。

这里是相同功能的另一个版本。

constexpr int f1(int k) {
    return k;
}
Run Code Online (Sandbox Code Playgroud)

这个很好用,很好用。所以问题是,为什么这里的生命周期也k开始于返回值的初始值设定项之外,或者不是,或者这是因为 RVO 并且从技术上讲,如果只是遵循标准,这也应该是一个错误?

还有另一个问题,这个问题实际上是从这个问题产生的。我正在尝试编写constexprIPv4 类。为此,我使用了带有std::string_view. 所以我能够在编译时使用 gcc 10.3 和 -std=c++20

constexpr IPv4 myIP{"192.168.0.0"};
constexpr size_t count = myIP.countOfDots(); // calls std::count which is constexpr in C++20
Run Code Online (Sandbox Code Playgroud)

现在我想验证 IP 是否正确,所以我需要检查点数是否等于 3,我可以在这里轻松完成

if constexpr (count != 3)
Run Code Online (Sandbox Code Playgroud)

问题是如何将它组织成某个函数,这也将允许我在编译时对任何给定的 IP 进行这样的检查,基本上我想要这样的东西

constexpr bool validateIP(const IPv4& ip);
Run Code Online (Sandbox Code Playgroud)

和上面的例子一样,我不能只在那个函数中使用这个

constexpr size_t count = ip.countOfDots();
Run Code Online (Sandbox Code Playgroud)

那么有可能按照我想要的方式做吗?

sup*_*per 8

一个函数constexpr意味着该函数可能在编译时被评估。但是,该函数还必须可以使用运行时值调用,并产生运行时结果。

constexpr必须是编译时常量的变量。时期。

这对您的validateIP功能意味着您不需要 make count constexpr。您可以编写一个函数并将其标记为constexpr.

当您使用编译时常量调用该函数时,它将在编译时进行评估。

如果您使用运行时值调用它,它将在运行时进行评估。

#include <string_view>
#include <iostream>

constexpr bool validateIP(const std::string_view& ip) {
    int count = 0;
    for (auto& c : ip) {
        if (c == '.') {
            ++count;
        }
    }

    return count == 3;
}

int main()
{
    // Assigning the value to a constexpr is not needed to make the function
    // be evaluated at compile time, but it proves that it is in this case
    constexpr auto isValid1 = validateIP("123.456.789.0");

    std::cout << isValid1;
}
Run Code Online (Sandbox Code Playgroud)

  • 我明白我真的误解了 ```constexpr``` 函数的含义,现在清楚了,谢谢您的帮助:) (2认同)