# void_t

suggest change`void_t`

is a meta-function that maps any (number of) types to type `void`

. The primary purpose of `void_t`

is to facilitate writing of type traits.

`std::void_t`

will be part of C++17, but until then, it is extremely straightforward to implement:

`template <class...> using void_t = void;`

Some compilers require a slightly different implementation:

```
template <class...>
struct make_void { using type = void; };
template <typename... T>
using void_t = typename make_void<T...>::type;
```

The primary application of `void_t`

is writing type traits that check validity of a statement. For example, let’s check if a type has a member function `foo()`

that takes no arguments:

```
template <class T, class=void>
struct has_foo : std::false_type {};
template <class T>
struct has_foo<T, void_t<decltype(std::declval<T&>().foo())>> : std::true_type {};
```

How does this work? When I try to instantiate `has_foo<T>::value`

, that will cause the compiler to try to look for the best specialization for `has_foo<T, void>`

. We have two options: the primary, and this secondary one which involves having to instantiate that underlying expression:

- If
`T`

*does*have a member function`foo()`

, then whatever type that returns gets converted to`void`

, and the specialization is preferred to the primary based on the template partial ordering rules. So`has_foo<T>::value`

will be`true`

- If
`T`

*doesn’t*have such a member function (or it requires more than one argument), then substitution fails for the specialization and we only have the primary template to fallback on. Hence,`has_foo<T>::value`

is`false`

.

A simpler case:

```
template<class T, class=void>
struct can_reference : std::false_type {};
template<class T>
struct can_reference<T, std::void_t<T&>> : std::true_type {};
```

this doesn’t use `std::declval`

or `decltype`

.

You may notice a common pattern of a void argument. We can factor this out:

```
struct details {
template<template<class...>class Z, class=void, class...Ts>
struct can_apply:
std::false_type
{};
template<template<class...>class Z, class...Ts>
struct can_apply<Z, std::void_t<Z<Ts...>>, Ts...>:
std::true_type
{};
};
template<template<class...>class Z, class...Ts>
using can_apply = details::can_apply<Z, void, Ts...>;
```

which hides the use of `std::void_t`

and makes `can_apply`

act like an indicator whether the type supplied as the first template argument is well-formed after substituting the other types into it. The previous examples may now be rewritten using `can_apply`

as:

```
template<class T>
using ref_t = T&;
template<class T>
using can_reference = can_apply<ref_t, T>; // Is T& well formed for T?
```

and:

```
template<class T>
using dot_foo_r = decltype(std::declval<T&>().foo());
template<class T>
using can_dot_foo = can_apply< dot_foo_r, T >; // Is T.foo() well formed for T?
```

which seems simpler than the original versions.

There are post-C++17 proposals for `std`

traits similar to `can_apply`

.

The utility of `void_t`

was discovered by Walter Brown. He gave a wonderful presentation on it at CppCon 2016.