constexpr 和 std::cout 处理函数但不处理 lambda

constexpr and std::cout working on function but not in lambda

为什么 constexpr 不适用于 std::cout,但适用于 printf

#include <iostream>
constexpr void f() { std::cout << ""; } //error
constexpr void g() { printf(""); } //ok

为什么 std::cout 使用 lambdas constexpr

#include <iostream>
int main () {
    auto h = []() constexpr { std::cout << ""; }; //ok
}

没有。您需要使用它来强制编译时出错。

constexpr int a = f(), 0; // fails
constexpr int b = g(), 0; // fails

constexpr 从不产生常量表达式的函数是 ill-formed;无需诊断。这意味着编译器会尽最大努力检查是否是这种情况,但是您的程序已经有任何错误。似乎 gcc 看不出 printf 不是常量表达式。 clang errors at the definition.

从技术上讲,它不适用于其中任何一个。

来自[dcl.constexr]

For a constexpr function or constexpr constructor that is neither defaulted nor a template, if no argument values exist such that an invocation of the function or constructor could be an evaluated subexpression of a core constant expression, or, for a constructor, a constant initializer for some object ([basic.start.static]), the program is ill-formed, no diagnostic required.

f()g() 永远不是常量表达式(std::cout << xprintf() 都不是 constexpr 函数),所以 constexpr 声明是 ill-formed.但是 不需要编译器来对此进行诊断(在这种情况下,这可能很容易,但在一般情况下……没那么容易)。您看到的是您的编译器能够诊断出一个问题,但不能诊断出另一个问题。

但他们都错了。