考慮以下概念,它依賴于and的operator bool()轉換成員函式。std::is_lvalue_reference<T>std::is_const<T>
#include <type_traits>
template <typename T>
concept is_non_const_lvalue_reference =
std::is_lvalue_reference<T>{} && // Malformed for GCC 12.2 and MSVC 19.33
!std::is_const<std::remove_reference_t<T>>{};
static_assert(is_non_const_lvalue_reference<int&>);
static_assert(!is_non_const_lvalue_reference<int const&>);
static_assert(!is_non_const_lvalue_reference<int&&>);
請參閱https://compiler-explorer.com/z/G5ffeWfbx上的測驗。
GCC 和 MSVC 都正確報告回傳的型別std::is_lvalue_reference<T>{}不是布林值。但是 Clang 15 然后將隱式轉換應用于bool并認為上面的概念定義是合式的。相反,!std::is_const<...>{}由于運算子,運算式被認為是布爾運算式!。
問題: Clang 15 在執行隱式轉換時是否過于寬松bool?或者是 GCC 和 MSVC 的問題?也許它在 C 20 中未指定?
PS 是的,我知道我可以用 替換std::is_*<T>{}運算式std::is_*_v<T>,從而避免這個問題。但我想了解何時預期/允許執行隱式轉換。
uj5u.com熱心網友回復:
規則是,來自[temp.constr.atomic]/3:
要確定是否滿足原子約束,首先將引數映射和模板引數代入其運算式。如果替換導致無效型別或運算式,則不滿足約束。否則,如有必要,將執行左值到右值的轉換,并且
E應為 type 的常量運算式bool。
這里,std::is_lvalue_reference<T>{}是一個原子約束——所以它必須有型別bool。它沒有。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/534078.html
標籤:C C 20
