Document number: J16/07-0100 = WG21 N2240
Date: 2007-04-17
Author: Benjamin Kosnik <bkoz@redhat.com>
Library Working Group
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
.
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.
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.
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 .
|
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.
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
if_c
from MPL
documentation