Document number: J16/07-0100 = WG21 N2240
Date: 2007-04-17
Author: Benjamin Kosnik <bkoz@redhat.com>
Library Working Group

Two missing traits: enable_if and conditional



Introduction.

Similar to two other papers pointing out weaknesses or errors in TR1's type_traits offerings, this paper presents two notable omissions that are in wide use: traits: enable_if, and conditional.

enable_if

This is an object for compile-type conditional type existence, useful for SFINAE and clean implementation of overload sets.

  template<bool _Cond, typename _Tp>
    struct enable_if 
    { };

  template<typename _Tp>
    struct enable_if<true, _Tp>
    { typedef _Tp type; };

As defined above, enable_if::type is equal to the second parameter only if the condition argument is true.

There has been some murmuring in the greater C++ community that this trait will prove less useful in the presence of concepts. However, these voices are indistinct. It is not clear if concepts will eliminate all uses of this trait.

conditional

This is an object for compile-type conditional type selection.

  template<bool _Cond, typename _Iftrue, typename _Iffalse>
    struct conditional
    { typedef _Iftrue type; };

  template<typename _Iftrue, typename _Iffalse>
    struct conditional<false, _Iftrue, _Iffalse>
    { typedef _Iffalse type; };

As defined above, conditional::type is equal to the second parameter if the first (condition) parameter is true, and is equal to the third parameter if the condition parameter is false.

Wording.

Extend the synopsis of 20.4.2 to include the following:

// [20.4.2] other transformations:
template <bool, typename Tp = void> struct enable_if;
template <bool, typename IfTrue, typename IfFalse> struct conditional;

Add the following row to Table 46 (Other transformations):

Template Condition Comments
template <bool B, typename T = void> struct enable_if;   If B is true, the member typedef type shall equal T
template <bool B, typename IfTrue, typename IfFalse> struct conditional;   If B is true, the member typedef type shall equal IfTrue. If B is false, the member typedef type shall equal IfFalse.

Implementation and usage notes.

From a quick scan, the enable_if trait has been formalized in the Boost type_traits utilities since 2003, and since May 2003 in GNU libstdc++. Both spellings and signatures are the same. In addition, Boost duplicates this functionality in the MPL libraries with eval_if_c function. So, Boost really has this trait twice: it must be that useful!

Likewise, the __conditional_type trait has been used since August, 2006 in GNU libstdc++, with earlier spellings of both cond_type starting in June, 2005 and IF also starting in 2005. Boost has had this functionality since approximately 2002 as part of the MPL library, and spells this as if_c. In addition, Boost duplicates this functionality in boost/xpressive/proto/transform/conditional.hpp, spelling it conditional. RogueWave may have some of this functionality in the macro RW_CONDITIONAL_TYPENAME. Boost documentation points to the discovery, use, and evolution of this trait from 1995 to 2000 to the present day.

google codesearch for enable_if lang:"c++" yields 100 hits, with users in boost, loki, k3d, lyx, polymake, LLVM, gcc/libstdc++, cca-forum.org, cgal, inkscape, HepMC, orocos, QuantLib, and so on and so on as this is up to page 5 of 10.

google codesearch for eval_if_c lang:"c++" yields 9 hits, with all users in boost.

google case-sensitive codesearch for if_c lang:"c++" yields 300 hits but not all unique to this specific trait. Still, verified uses in boost, k3d, in secondlife's linden sources, lyx, glite, cca-forum.org, StatisticsTesting, CGAL, etc.

google codesearch for cond_type lang:"c++" yields nothing useful, due to a lot of hits for second_type.

google codesearch for conditional type lang:"c++" yields 200 hits, with some likely candidates, but many false matches.

google codesearch for conditional_type lang:"c++" yields 9 hits, all users in gcc/libstdc++. More interesting searches are possible with variations of "conditional" "__conditional," "type," and "trait." Some of these users are, on inspection, looking for ways to do conditional type computation.

References.

Howard E. Hinnant, Minor Modifications to the type traits Wording Revision 1, N2157=07-0017, January 12,2007.

Thorsten Ottosen, Yet another type-trait: decay, N2069, September 8, 2006

Aleksey Gurtovo and David Abrahams, 2.1. Conditional type selection, The Boost C++ Metaprogramming Library

Pete Becker, Programming Languages C++, N2135 06-0205

libstdc++ mailing list on missing traits, September 14, 2006 discussion

libstdc++ ext/type_traits file

boost enable_if documentation

boost eval_if_c from MPL documentation

boost if_c from MPL documentation