integral_constant
needs a spring cleanSection: 21.3.4 [meta.help] Status: NAD Submitter: Alisdair Meredith Opened: 2009-09-05 Last modified: 2016-01-28
Priority: Not Prioritized
View all other issues in [meta.help].
View all issues with NAD status.
Discussion:
The specification of integral_constant
has been inherited
essentially unchanged from TR1:
template <class T, T v> struct integral_constant { static const T value = v; typedef T value_type; typedef integral_constant<T,v> type; };
In light of 0x language changes there are several things we might consider changing, notably the form of specification for value.
The current form requires a static data member have storage allocated for it, where we could now implement without this using the new enum syntax:
template <class T, T v> struct integral_constant { enum : T { value = v }; typedef T value_type; typedef integral_constant type; };
The effective difference between these two implementation is:
&integral_constant<T,v>::value;
Also note the editorial change to drop the explicit qualification of
integral_constant
in the typedef type
. This makes it quite clear we
mean the current instantiation, and cannot be mistaken for a recursive
metaprogram.
Even if we don't mandate this implementation, it would be nice to give vendors freedom under QoI to choose their preferred representation.
The other side of this issue is if we choose to retain the static
constant form. In that case we should go further and insist on
constexpr
, much like we did throughout numeric_limits
:
template <class T, T v> struct integral_constant { static constexpr T value = v; typedef T value_type; typedef integral_constant type; };
[Footnote] It turns out constexpr
is part of the Tentatively Ready
resolution for 1019. I don't want to interfere with that issue, but
would like a new issue to consider if the fixed-base enum implementation
should be allowed.
[ 2009-09-05 Daniel adds: ]
I think that the suggested resolution is incomplete and may have some possible unwanted side-effects. To understand why, note that
integral_constant
is completely specified by code in 21.3.4 [meta.help]. While this is usually considered as a good thing, let me give a possible user-defined specialization that would break given the suggested changes:enum NodeColor { Red, Black }; std::integral_constant<NodeColor, Red> red;The reason why that breaks is due to the fact that current core language rules does only allow integral types as enum-bases, see 9.7.1 [dcl.enum]/2.
So, I think that we cannot leave the implementation the freedom to decide which way they would like to provide the implementation, because that is easily user-visible (I don't speak of addresses, but of instantiation errors), therefore if applied, this should be either specified or wording must be added that gives a note about this freedom of implementation.
Another possible disadvantage seems to me that user-expectations are easy to disappoint if they see a failure of the test
assert(typeid(std::integral_constant<int, 0>::value) == typeid(int));or of
static_assert(std::is_same<decltype(std::integral_constant<int, 0>::value), const int>::value, "Bad library");
[ 2010-01-14 Moved to Tentatively NAD after 5 positive votes on c++std-lib. ]
Rationale:
We think that the suggested resolution is incomplete and may have some possible unwanted side-effects. (see Daniel's 2009-09-05 comment for details).
Proposed resolution: