![](/img/trans.png)
[英]Can C++ constexpr function actually accept non-constant expression as argument?
[英]Can lambda() that never evaluates to a constant expression be a `constexpr`-function in C++?
根据https://en.cppreference.com/w/cpp/language/lambda,Lambda的operator()
是隐式constexpr
当此说明符 (
constexpr
) 不存在时,函数调用运算符或任何给定的运算符模板特化无论如何都将是constexpr
,如果它恰好满足所有constexpr
函数要求
以及根据https://en.cppreference.com/w/cpp/language/constexpr对constexpr
函数的要求
至少存在一组参数值,使得函数的调用可以是核心常量表达式的计算子表达式(对于构造函数,在常量初始值设定项中使用就足够了)(自 C++14 起)。 违反此项目符号不需要诊断。
在下一个例子中,函数t()
总是通过调用 lambda l()
来抛出异常:
auto l = []()->bool { throw 42; };
constexpr bool t() { return l(); }
GCC 拒绝此函数并显示错误:
call to non-'constexpr' function '<lambda()>'
但 Clang 接受程序(直到函数t()
用于常量评估),这意味着它认为l()
是constexpr
函数,演示: https ://gcc.godbolt.org/z/j1z7ee3Wv
它是 Clang 中的错误,还是这种编译器行为也是可以接受的?
当您实际尝试在需要常量表达式的上下文中使用t()
的结果时,所有三个编译器都会发出错误。 例如:
auto l = []()->bool { throw 42; };
constexpr bool t() { return l(); }
template <bool x>
struct dummy {};
int main() {
dummy< t() > d; // error: t() is not a constant expression
}
正如 NathanOliver 在评论中提到的,您的引述已经指出:
[...] 违反此项目不需要诊断。
编译器不必证明不存在允许函数返回常量表达式的参数值集。 另一方面,编译器可以轻松验证给定的参数值,结果不是常量表达式。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.