incubator-stdcxx-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Martin Sebor <se...@roguewave.com>
Subject Re: tests/utilities/20.meta.help.cpp
Date Tue, 24 Jun 2008 00:46:38 GMT
Travis Vitek wrote:
>  
> 
> Martin Sebor wrote:
>> Travis Vitek wrote:
>>>  
>>> Eric Lemings wrote:
>>>> Just a brief side note.  I was just reviewing this test and 
>>>> noticed that
>>>> pointers are not tested though they are valid scalar types 
>> suitable for
>>>> use as integral_constant parameters.  I think references 
>> may be valid
>>>> parameters also.
>>>>
>>> I'm not sure.
>>>
>>> The first thing that jumps to mind is that a pointer is not of
>>> 'integral' type. An enumeration isn't really an integral type either,
>>> but they are implicitly convertible to one. Pointers aren't 
>> convertible
>>> to integral type without a cast.
>>>
>>> According to temp.arg.nontype, a non-type, non-template template
>>> parameter must be one of
>>>
>>>   -- an integral constant expression
>>>   -- the name of a non-type template-parameter
>>>   -- the address of an object or function with external linkage...
>>>   -- a constant expression that evaluates to a null pointer value
>>>   -- a constant expression that evaluates to a null member 
>> pointer value
>>>   -- a pointer to member
>>>
>>> So, yes, it is legal to use a pointer as a non-type template 
>> parameter.
>>> The issue I have is that the integral_constant<T,V> is supposed to
>>> define an integral constant of type T with value V. Section 
>> expr.const
>>> says that a constant expression is an integral constant 
>> expression if it
>>> is of integral or enumeration type. An integral constant 
>> expression can
>>> be used as an array bound, a case expression, a bit field length,
>>> enumeration initializer, static member initializer and as integral or
>>> enumeration non-type template arguments.
>>>
>>> I'm pretty sure you can't use a pointer value as an array bound, case
>>> expression, bit field length or enumeration initializer, so 
>> they aren't
>>> really integral constants.
>>>
>>> So I am sure you can instantiate std::integral_constant<void
>>> (class_t::*)(), &class::method>, but I'm not sure if it 
>> something that
>>> should be tested.
>> If there's an implementation technique that would make the
>> instantiation ill-formed then I think it should be tested.
> 
> According to class.mem (p4) and class.static.data (p4) you aren't
> allowed to initialize static members using a constant-initializer (i.e.
> in the member declaration) if they are not of const integral or const
> enumeration type. So the above instantiation on member pointer should be
> prevented by the compiler. A quick test with msvc-8.0 and gcc-4.3 show
> that this is the case.

Good point!

> 
> The following would be legal, but I'm already testing integral constants
> for all integral types and an enum type, so I think I'm covered.
> 
>> More important, though, the standard should specify the
>> requirements on the template arguments. If there are no
>> such requirements for something as fundamental as
>> integral_const, either in the latest working draft or
>> in one of the concepts papers (such as N2622), we should
>> at least bring it up on the list and/or open an issue to
>> have the spec clarified.
> 
> The standard does specify the requirements of the template arguments,
> but only through association (to be an integral constant member, it has
> to be a const static that is initialized with a constant-initializer,

Is this specified anywhere else besides the definition of the
class in [meta.help]? If not, I'm not sure that every detail
of a class definition shown in the spec qualifies as a normative
requirement.

> and a constant initializer only works for enum and integral types). Is
> this significant enough to warrant bringing up an issue?

IMO, the class should have an explicit requirement on the first
template argument. If there isn't one I would propose adding
paragraph 2 with the text:

   -2- The template parameter T shall have an integral type (3.9.1).
       integral_constant<T>::value shall be a integral constant
       expression (5.19).

With concepts, we would change the definition of the class like
this (I think):

    template <IntegralConstantExpressionType T, T v>
    struct integral_constant {
        // ...
    };

Strangely, this isn't in N2625:
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2625.pdf

Incidentally, it also seems to me that value should be declared
constexpr (both in our implementation and in the spec).

> 
> Travis


Mime
View raw message