Title
integral_constant needs a spring clean
Status
nad
Section
[meta.help]
Submitter
Alisdair Meredith

Created on 2009-09-05.00:00:00 last changed 164 months ago

Messages

Date: 2010-10-21.18:28:33

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).

Date: 2010-01-14.00:00:00

[ 2010-01-14 Moved to Tentatively NAD after 5 positive votes on c++std-lib. ]

Date: 2009-09-05.00:00:00

[ 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 [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 [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");
Date: 2009-09-05.00:00:00

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:

  1. No requirement to allocate storage for data member (which we hope but do not guarantee compilers strip today)
  2. You can no longer take the address of the constant as &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.

History
Date User Action Args
2010-10-21 18:28:33adminsetmessages: + msg1133
2010-10-21 18:28:33adminsetmessages: + msg1132
2010-10-21 18:28:33adminsetmessages: + msg1131
2009-09-05 00:00:00admincreate