My problem can be summarised in following code
#include <variant>
int main()
{
using V = std::variant<int, std::nullptr_t>;
V a = 0;
V b = nullptr;
a < b;
}
I want to have variant with std::nullptr_t
inside and I want to be able to compare such variants. It was working on Visual Studio 2018 (version 16.1.X), but it won't compile on version 16.3.1. I thought that this is a bug in the compiler, but I'm not sure now. I cannot find anything about std::nullptr_t
supporting comparison operators and even GCC and Clang seems to disagree. Should it be working, or not? Also, if no is the correct answer, is there a way to make it work? Defining of the operator for std::nullptr_t
doesn't seem to work.
inline bool operator<(std::nullptr_t, std::nullptr_t)
{
return false;
}
As defining relational operators can be done only on class parameter.
Thanks.
The type std::nullptr_t
does not have any relational operators defined for it. It is only equality-comparable (that is nullptr == nullptr
is valid and true
, but nullptr < nullptr
is ill-formed). You could argue that this is a defect, and we could define the relational operators such that nullptr < nullptr
is false
and nullptr <= nullptr
is true
, etc. But that is the way it is.
Using <
on variant<Ts...>
requires <
to be a valid operation on each type in Ts...
, which is not the case in your example, hence a < b
is ill-formed. This isn't a bug in any of the compilers or the libraries, it's the expected behavior.
The only way to make <
work here is to provide types that actually have a <
- that is, wrap std::nullptr_t
in some other type that actually is ordered. Do you need specifically std::nullptr_t
? Maybe std::monostate
, which has all six comparisons, is a better choice?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With