I'm using std::variant
to specify the types of properties that an entity in my project may have, and stumbled upon this code from cppreference:
std::visit([](auto&& arg)
{
using T = std::decay_t<decltype(arg)>;
if constexpr (std::is_same_v<T, int>)
std::cout << "int with value " << arg << '\n';
else if constexpr (std::is_same_v<T, long>)
std::cout << "long with value " << arg << '\n';
else if constexpr (std::is_same_v<T, double>)
std::cout << "double with value " << arg << '\n';
else if constexpr (std::is_same_v<T, std::string>)
std::cout << "std::string with value " << std::quoted(arg) << '\n';
else
static_assert(always_false_v<T>, "non-exhaustive visitor!");
}, w);
always_false_v
is defined as
template<class>
inline constexpr bool always_false_v = false;
I get that this checks at compile time if I'm handling all of the types in my variant which is pretty cool and helpful, but I'm puzzled as to why always_false_v<T>
is required.
If I remove a branch from the if
s, intellisense in Visual Studio immediately sets red squigglies because the static_assert
fails.
If I replace always_false_v<T>
with false
, intellisense doesn't complain but the static assert fails when I try to build.
Why is just false
not enough? I would expect the else
to never execute even at compile time, if it executes all the time, why is always_false_v<T>
not equivalent to false
(it looks like it's true
which surely it cannot be)?