Why isn't std::variant allowed to equal compare with one of its alternative types?
A variant may have multiple duplicates of the same type. E.g. std::variant<int, int>
.
A given instance of std::variant
compares equal to another if and only if they hold the same variant alternative and said alternatives' values compare equal.
Thus, a std::variant<int, int>
with index()
0 compares not equal to a std::variant<int, int>
with index()
1, despite the active variant alternatives being of the same type and same value.
Because of this, a generic "compare to T
" was not implemented by the standard. However, you are free to design your own overload of the comparison operators using the other helper utilities in the <variant>
header (e.g. std::holds_alternative
and std::get<T>
).
I can't answer the why part of the question but since you think it would be useful to be able to compare a std::variant<T1, T2>
with a T1
or T2
, perhaps this can help:
template<typename T, class... Types>
inline bool operator==(const T& t, const std::variant<Types...>& v) {
const T* c = std::get_if<T>(&v);
if(c)
return *c == t;
else
return false;
}
template<typename T, class... Types>
inline bool operator==(const std::variant<Types...>& v, const T& t) {
return t == v;
}
It is an arbitrary decision by the standards committee.
Ok, not quite arbitrary. The point is you have a scale* of strictness of comparison, with points such as:
- Most-strict: Only variants can equal each other, and they need to match both in the sequence-of-alternatives (i.e. the type), the actual alternative (the index, really, since you can have multiple identical-type alternatives) and in value.
- Less-Strict: Equality of both the variant alternative, as a type and the value, but not of the sequence-of-alternatives, nor the index within that sequence (so the same value within two distinct alternatives of the same type would be equal).
- Most-relaxed: Equality of the value in the active alternative, with implicit conversion of one of the elements if relevant.
These are all valid choices. the C++ committee made the decision based on all sorts of extrinsic criteria. Try looking up the std::variant
proposal, as perhaps it says what these criteria are.
(*) - A lattice actually.