You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@stdcxx.apache.org by Eric Lemings <Er...@roguewave.com> on 2008/06/20 20:32:22 UTC
tests/utilities/20.meta.help.cpp
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.
Brad.
Re: tests/utilities/20.meta.help.cpp
Posted by Martin Sebor <se...@roguewave.com>.
Martin Sebor wrote:
> Travis Vitek wrote:
>>
[...]
> 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>
Actually, I don't think this is quite sufficient. T is more
constrained than that. If there were an OR in Concepts it
would be:
template <IntegralConstantExpressionType T, T v>
requires IntegralType<T> || EnumerationType<T>
struct integral_constant;
I've written up an issue/proposal to fix this without using
concepts that I plan to send to the list shortly unless you
see a better way of dealing with it. Here's the proposal:
Add a new paragraph to [meta.help] with the following
requirement:
-2- The template parameter T shall have an integral type
(3.9.1) or be an enumeration (3.9.2).
integral_constant<T>::value shall be an integral
constant expression (5.19).
In addition, declare the value data member of the template
constexpr:
template <class T, T v>
struct integral_constant {
typedef T value_type;
typedef integral_constant<value_type, v> type;
static constexpr value_type value = 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
>
Re: tests/utilities/20.meta.help.cpp
Posted by Martin Sebor <se...@roguewave.com>.
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
RE: tests/utilities/20.meta.help.cpp
Posted by Travis Vitek <Tr...@roguewave.com>.
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.
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,
and a constant initializer only works for enum and integral types). Is
this significant enough to warrant bringing up an issue?
Travis
Re: tests/utilities/20.meta.help.cpp
Posted by Martin Sebor <se...@roguewave.com>.
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.
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.
Martin
>
>> Brad.
>>
RE: tests/utilities/20.meta.help.cpp
Posted by Eric Lemings <Er...@roguewave.com>.
> -----Original Message-----
> From: Travis Vitek [mailto:Travis.Vitek@roguewave.com]
> Sent: Friday, June 20, 2008 12:59 PM
> To: dev@stdcxx.apache.org
> Subject: RE: tests/utilities/20.meta.help.cpp
>
>
...
>
> 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.
Almost sounds like a rudimentary function object, doesn't it? :)
template <
template < class PtrType, PtrType Ptr> class FuncPtr,
class ReturnType, class... ParamTypes
> struct FuncObj;
Brad.
RE: tests/utilities/20.meta.help.cpp
Posted by Travis Vitek <Tr...@roguewave.com>.
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.
>Brad.
>