我試圖更改以下示例概念代碼,該代碼在某些輸入下導致錯誤而不是評估錯誤:
template <typename T>
constexpr bool inner = T::prop;
template <typename T>
concept outer = inner<T>;
struct pass {static constexpr bool prop = true;};
struct fail {static constexpr bool prop = false;};
struct bad_fail {static constexpr std::tuple<> prop{};};
static_assert(outer<pass>);
static_assert(not outer<fail>);
static_assert(not outer<bad_fail>);
這有編譯錯誤cannot convert 'const std::tuple<>' to 'const bool'
。
我試圖僅評估inner
何時使用requires
子句進行編譯:
template <typename T>
constexpr bool inner = T::prop;
template <typename T>
concept outer = []() consteval -> bool {
if constexpr (
requires() {{
inner<T>
} -> std::same_as<const bool&>;}
) {
return inner<T>;
} else {
return false;
}
}();
struct pass {static constexpr bool prop = true;};
struct fail {static constexpr bool prop = false;};
struct bad_fail {static constexpr std::tuple<> prop{};};
static_assert(outer<pass>);
static_assert(not outer<fail>);
static_assert(not outer<bad_fail>);
這會導致一個令人困惑的錯誤:
error: non-constant condition for static assertion ... static_assert(not outer<bad_fail>)
cannot convert 'const std::tuple<>' to 'const bool'
似乎來自 2nd的相同inner
。(編譯器沒有指定)
然后我嘗試將編譯檢查和真值檢查組合成一個子句static_assert
中的檢查:requires
template <typename T>
constexpr bool inner = T::prop;
template <typename T>
concept outer = requires() {{
[]() constexpr {
static_assert(inner<T>);
}()
} -> std::same_as<void>;};
struct pass {static constexpr bool prop = true;};
struct fail {static constexpr bool prop = false;};
struct bad_fail {static constexpr std::tuple<> prop{};};
static_assert(outer<pass>);
static_assert(not outer<fail>);
//static_assert(not outer<bad_fail>);
這會導致一個令人困惑的錯誤:
error: static assertion failed ... static_assert(not outer<fail>)
這令人困惑,因為:
error: static assertion failed ... static_assert(inner<T>)
也拋出,暗示static_assert
轉義requires
子句。果然是真的:
template <std::monostate>
concept should_false = requires() {{
[]() constexpr {
static_assert(false);
}()
} -> std::same_as<void>;};
因為這有編譯錯誤error: static assertion failed ... static_assert(false)
!
如何outer<bad_fail>
在沒有編譯錯誤的情況下評估為 false?
uj5u.com熱心網友回復:
可以使用requires
-clause 進行初始化inner
,它首先要求回傳型別T::prop
必須是const bool&
,然后使用嵌套requires
的 withT::prop
作為其值
#include <concepts>
template <typename T>
constexpr bool inner = requires {
{T::prop} -> std::same_as<const bool&>;
requires T::prop;
};
template <typename T>
concept outer = inner<T>;
演示
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/470095.html
上一篇:用字串中的雙精度替換每個出現
下一篇:makefile中的回圈main