Estou vendo algum comportamento inesperado ao usar o std::variant::operator<
. Na situação em que o tipo possui um operador de conversão bool implícito e seu operador less não é uma função membro (em C++20 com compilador mscv 19.38).
#include <variant>
struct Foo {
int x;
int y;
#ifndef DROP_CAST_OP
constexpr operator bool() const { return x || y; }
#endif
#ifdef USE_SPACESHIP
constexpr auto operator<=>(const Foo&) const noexcept = default;
#else
friend constexpr bool operator<(const Foo& a, const Foo& b) noexcept
{
return a.x < b.x || (a.x == b.x && a.y < b.y);
}
#endif
};
using TestVariant = std::variant<Foo, int>;
constexpr Foo fooA { 0, 1 };
constexpr Foo fooB { 1, 0 };
constexpr std::variant<Foo, int> varA = fooA;
constexpr std::variant<Foo, int> varB = fooB;
static_assert(fooA < fooB);
static_assert(varA < varB);
https://godbolt.org/z/1zfq5dq1r
Observe que a asserção começa a passar quando uma das seguintes condições é atendida:
- use C++17 em vez de C++20
- use o operador de comparação de três vias em vez do operador de função livre menos
- não definindo conversão implícita para operador bool
- marcando o operador bool de conversão como explícito
Todos os compiladores têm o mesmo comportamento.