Skip to content

Instantly share code, notes, and snippets.

@ldionne
Created October 7, 2014 14:44
Show Gist options
  • Select an option

  • Save ldionne/22aa85bbe10d51fff585 to your computer and use it in GitHub Desktop.

Select an option

Save ldionne/22aa85bbe10d51fff585 to your computer and use it in GitHub Desktop.
NXXXX: Flexible partial specialization with `when` and `when_valid`

Flexible partial specialization with when and when_valid

  • Document Number: NXXXX
  • Date: 2014-10-07
  • Programming Language C++, Library Evolution Working Group
  • Reply-to: Louis Dionne [email protected]

Introduction

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.

Motivation and Scope

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
{ };

Design Decisions

TODO

Technical Specifications

Add the following to <utility> (or <type_traits>):

namespace std {
    template <bool>
    struct when;

    template <typename ...>
    using when_valid = when<true>;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment