I asked a question that has several references to the code:
template
using void_t = void;
I believe I have a generally
I don't think the shown example really shows what void_t
is good for as it only shows one use case, but when you look at
template
struct has_to_string()))>
>
: std::true_type { };
it is not so much different from
template
struct has_to_string()), void())
>
: std::true_type { };
And for this statement:
The former version is much easier to read and
void_t
doesn't requiredecltype
to work.
I think the advantage in readability is quite small and the second part makes no sense, when decltype
doesn't work, SFINAE kicks in as expected.
One example where void_t
is more useful is the one from the proposal:
// primary template handles types that have no nested ::type member
template< class, class = void_t<> >
struct has_type_member
: std::false_type { };
// specialization recognizes types that do have a nested ::type member
template< class T >
struct has_type_member>
: std::true_type { }
As you can see, even the primary template uses void_t
to increase the readability as it now matches the specialization. That is not strictly necessary, but I like it. The real power comes when you think about the alternatives. Without void_t
, the specialization is now more complicated:
template< class T >
struct has_type_member
: std::true_type { }
wouldn't work as T::type
names a type, not an expression. You therefore need
template< class T >
struct has_type_member(), void())>
: std::true_type { }
The whole expression becomes longer, more tricky and it might suffer from edge-cases you forgot to handle. This is where void_t
really helps, the other uses are then just a small improvement and they increase consistency.