1019. Make integral_constant objects useable in integral-constant-expressions

Section: 23.15.3 [meta.help] Status: C++11 Submitter: Alisdair Meredith Opened: 2009-03-11 Last modified: 2016-02-10

Priority: Not Prioritized

View all other issues in [meta.help].

View all issues with C++11 status.

Discussion:

Addresses UK 205 [CD1]

integral_constant objects should be usable in integral-constant-expressions. The addition to the language of literal types and the enhanced rules for constant expressions make this possible.

[ Batavia (2009-05): ]

We agree that the static data member ought be declared constexpr, but do not see a need for the proposed operator value_type(). (A use case would be helpful.) Move to Open.

[ 2009-05-23 Alisdair adds: ]

The motivating case in my mind is that we can then use true_type and false_type as integral Boolean expressions, for example inside a static_assert declaration. In that sense it is purely a matter of style.

Note that Boost has applied the non-explicit conversion operator for many years as it has valuable properties for extension into other metaprogramming libraries, such as MPL. If additional rationale is desired I will poll the Boost lists for why this extension was originally applied. I would argue that explicit conversion is more appropriate for 0x though.

[ 2009-07-04 Howard adds: ]

Here's a use case which demonstrates the syntactic niceness which Alisdair describes:

#define requires(...) class = typename std::enable_if<(__VA_ARGS__)>::type

template <class T, class U,
    requires(!is_lvalue_reference<T>() ||
              is_lvalue_reference<T>() && is_lvalue_reference<U>()),
    requires(is_same<typename base_type<T>::type,
                     typename base_type<U>::type>)>
inline
T&&
forward(U&& t)
{
    return static_cast<T&&>(t);
}

[ 2009-07 post-Frankfurt: ]

Move to Tentatively Ready.

[ 2009 Santa Cruz: ]

Moved to Ready for this meeting.

Proposed resolution:

Add to the integral_constant struct definition in 23.15.3 [meta.help]:

template <class T, T v>
struct integral_constant {
  static constexpr T value = v;
  typedef T value_type;
  typedef integral_constant<T,v> type;
  constexpr operator value_type() { return value; }
};