#include <iostream>
#include <string>
#include <variant>
int main()
{
std::variant<std::string, bool> v{ "hasta la vista" };
std::cout << std::boolalpha << std::holds_alternative<std::string>(v) << ' ' << std::holds_alternative<bool>(v) << std::endl;
}
$ g++ std_alternative.cpp
$ ./a.out
true false
$ g++ -std=c++17 std_alternative.cpp
$ ./a.out
false true
Why is the output different? Which is correct according to c++17? What should I do so that my code works on both versions of GCC the same way?
struct explicit_bool {
bool b = false;
template<class T,
std::enable_if_t<std::is_same_v<T, bool>, bool> = true
>
explicit_bool( T v ):b(v){}
explicit_bool(explicit_bool const&) noexcept=default;
explicit_bool& operator=(explicit_bool const&)& noexcept=default;
explicit_bool()noexcept=default;
~explicit_bool()noexcept=default;
bool operator!() const { return !b; }
explicit operator bool() const { return b; }
};
store one of these (instead of a bool
).
It only accepts actual bool
s and other explicit_bool
s as arguments.
You may have to add some explicit casts to-from bool
in your code after doing this. It may be of interest to you that (bool)
as a cast always does the exact same thing as static_cast<bool>
does, unlike many other C-style casts compared to C++ style casts; this can make it less painful. Another choice is !!
, which converts most types to bool
implicitly.