![](/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.