简体   繁体   English

使用 C++20 将 std::variant 与 int 进行比较 <=> 不是常量表达式

[英]Compare std::variant with int using C++20 <=> is not a constant expression

Since the std::variant is not allowed to compare with one of its alternative types in the standard library, I am implementing the compare function using C++20 <=> operator:由于std::variant不允许与标准库中的一种替代类型进行比较,因此我正在使用 C++20 <=>运算符实现比较 function:

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);
}

But when I testing the above function with my own defined std::variant :但是当我用我自己定义的std::variant测试上面的 function 时:

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 , GCC says:第二个断言无法编译,GCC 说:

<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

Why is v2 < 2 not a constant expression?为什么v2 < 2不是常量表达式? or it's just a GCC bug ?或者它只是一个GCC 错误 Weirder, when I change the second assertion to compare with double , this can compile:更奇怪的是,当我将第二个断言更改为与double进行比较时,可以编译:

static_assert(v2 < 2.0);

Update:更新:

Clang can pass three assertions, but MSVC can only pass the third assertion , it seems MSVC also has a bug. Clang 可以通过三个断言,但是 MSVC 只能通过第三个断言看来 MSVC 也有 bug。

The first example reduces to:第一个例子简化为:

#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);

Everything here is obviously a constant expression.这里的一切显然都是一个常数表达式。 The fact that strong_ordering::less can be converted to partial_ordering::less just fine while 1 <=> 2 can't be (on gcc) suggests that this is a bug in the compiler, rather than the library. strong_ordering::less可以转换为partial_ordering::less就好了,而1 <=> 2不能(在 gcc 上)表明这是编译器中的错误,而不是库中的错误。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM