- Document Number: NXXXX
- Date: 2014-10-07
- Programming Language C++, Library Evolution Working Group
- Reply-to: Louis Dionne [email protected]
This proposal adds two utilities, when and when_valid, that can be used to
partially specialize templates based on a compile-time condition and on the
validity of an expression, respectively.
N3911 proposes adding an alias template named void_t, which can be used
to partially specialize a template based on the validity of an expression.
However, to partially specialize a template based on a compile-time condition,
one has to use enable_if in conjunction with void_t. This proposal is a
minor generalization of void_t allowing both use cases without resorting to
enable_if.
Some questions regarding the name of void_t had also been raised in
N3911; this proposal also aims to resolve those issues.
Specifically, the intended usage of void_t is as follows:
template <typename, typename = void>
struct has_type_member : false_type { };
template <typename T>
struct has_type_member<T, void_t<typename T::type>>
: true_type
{ };However, if one wants to enable has_type_member based on a compile-time
condition, one has to use enable_if:
template <typename, typename = void>
struct has_type_member : false_type { };
template <typename T>
struct has_type_member<T, void_t<enable_if_t<SomePredicate<T>::value>>>
: true_type
{ };This is more complicated than it needs to be. This paper proposes adding the
following utilities to the std namespace:
template <bool>
struct when;
template <typename ...>
using when_valid = when<true>;With these utilities, one can still partially specialize has_type_member
based on the validity of an expression as follows:
template <typename, typename = when<true>>
struct has_type_member : false_type { };
template <typename T>
struct has_type_member<T, when_valid<typename T::type>>
: true_type
{ };But it is now easier to partially specialize has_type_member based on a
compile-time condition:
template <typename, typename = when<true>>
struct has_type_member : false_type { };
template <typename T>
struct has_type_member<T, when<SomePredicate<T>::value>>
: true_type
{ };TODO
Add the following to <utility> (or <type_traits>):
namespace std {
template <bool>
struct when;
template <typename ...>
using when_valid = when<true>;
}