Compare std::variant with int using C++20 <=> 不是常量表达式
Compare std::variant with int using C++20 <=> is not a constant expression
由于不允许 std::variant
与其在标准库中的替代类型之一进行比较,我正在使用 C++20 <=>
运算符实现比较函数:
template <typename... Args, typename T>
constexpr auto operator<=>(const std::variant<Args...>& v, const T& t) {
return std::visit([&t](const auto& u) -> std::partial_ordering {
if constexpr (requires { u <=> t; }) return u <=> t;
else return std::partial_ordering::unordered;
}, v);
}
但是当我用自己定义的 std::variant
:
测试上面的函数时
using Variant = std::variant<double, int, std::string_view>;
constexpr Variant v1{1.0};
constexpr Variant v2{1};
constexpr Variant v3{"hello"};
static_assert(v1 < 2);
// compile error
static_assert(v2 < 2);
static_assert(!(v3 > 2) && !(v3 < 2) && !std::is_eq(v3 <=> 2));
The second assertion couldn't compile,海湾合作委员会说:
<source>:19:17: error: non-constant condition for static assertion
19 | static_assert(v2 < 2);
| ^~~~~~~~~
<source>:19:24: in 'constexpr' expansion of 'operator<=><double, int, std::basic_string_view<char, std::char_traits<char> >, int>(v2, 2)'
<source>:19:17: error: '<anonymous>' is not a constant expression
为什么 v2 < 2
不是常量表达式?还是只是 GCC 错误?奇怪的是,当我更改第二个断言以与 double
进行比较时,这可以编译:
static_assert(v2 < 2.0);
更新:
Clang can pass three assertions, but MSVC can only pass the third assertion,MSVC好像也有bug
第一个例子简化为:
#include <compare>
// this one is okay
static_assert(std::partial_ordering(std::strong_ordering::less) < 0);
// this one fails with non-constant condition
static_assert(std::partial_ordering(1 <=> 2) < 0);
这里的一切显然都是常量表达式。 strong_ordering::less
可以转换为 partial_ordering::less
而 1 <=> 2
不能(在 gcc 上)这一事实表明这是编译器中的错误,而不是库中的错误。
由于不允许 std::variant
与其在标准库中的替代类型之一进行比较,我正在使用 C++20 <=>
运算符实现比较函数:
template <typename... Args, typename T>
constexpr auto operator<=>(const std::variant<Args...>& v, const T& t) {
return std::visit([&t](const auto& u) -> std::partial_ordering {
if constexpr (requires { u <=> t; }) return u <=> t;
else return std::partial_ordering::unordered;
}, v);
}
但是当我用自己定义的 std::variant
:
using Variant = std::variant<double, int, std::string_view>;
constexpr Variant v1{1.0};
constexpr Variant v2{1};
constexpr Variant v3{"hello"};
static_assert(v1 < 2);
// compile error
static_assert(v2 < 2);
static_assert(!(v3 > 2) && !(v3 < 2) && !std::is_eq(v3 <=> 2));
The second assertion couldn't compile,海湾合作委员会说:
<source>:19:17: error: non-constant condition for static assertion
19 | static_assert(v2 < 2);
| ^~~~~~~~~
<source>:19:24: in 'constexpr' expansion of 'operator<=><double, int, std::basic_string_view<char, std::char_traits<char> >, int>(v2, 2)'
<source>:19:17: error: '<anonymous>' is not a constant expression
为什么 v2 < 2
不是常量表达式?还是只是 GCC 错误?奇怪的是,当我更改第二个断言以与 double
进行比较时,这可以编译:
static_assert(v2 < 2.0);
更新:
Clang can pass three assertions, but MSVC can only pass the third assertion,MSVC好像也有bug
第一个例子简化为:
#include <compare>
// this one is okay
static_assert(std::partial_ordering(std::strong_ordering::less) < 0);
// this one fails with non-constant condition
static_assert(std::partial_ordering(1 <=> 2) < 0);
这里的一切显然都是常量表达式。 strong_ordering::less
可以转换为 partial_ordering::less
而 1 <=> 2
不能(在 gcc 上)这一事实表明这是编译器中的错误,而不是库中的错误。