簡體   English   中英

使用 C++20 將 std::variant 與 int 進行比較 <=> 不是常量表達式

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

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

但是當我用我自己定義的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));

第二個斷言無法編譯,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

為什么v2 < 2不是常量表達式? 或者它只是一個GCC 錯誤 更奇怪的是,當我將第二個斷言更改為與double進行比較時,可以編譯:

static_assert(v2 < 2.0);

更新:

Clang 可以通過三個斷言,但是 MSVC 只能通過第三個斷言看來 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 上)表明這是編譯器中的錯誤,而不是庫中的錯誤。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM