member template partial specialization

K

Kai-Uwe Bux

Hi folks,


I would like to know which clause of the standard rules out this:

template < typename eval >
struct recursive_template {

typedef typename eval::enum_type Enum;

template < Enum first, Enum last >
struct range {

range<first+1,last> data;

};// range

template < Enum val > // line 13
struct range<val,val> {};

}; // recursive_template


Comeau rejects this code saying:

Comeau C/C++ 4.3.3 (Aug 6 2003 15:13:37) for ONLINE_EVALUATION_BETA1
Copyright 1988-2003 Comeau Computing. All rights reserved.
MODE:strict errors C++

"ComeauTest.c", line 13: error: the type of partial specialization template
parameter constant "val" depends on another template parameter
template < Enum val >
^

I found [14.5.4/9]:

... - The type of a template parameter corresponding to a specialized
non-type argument shall not be dependent on a parameter of the
specialization. [Example:
template <class T, T t> struct C {};
template <class T> struct C<T, 1>; // error
template< int X, int (*array_ptr)[X] > class A {};
int array[5];
template< int X > class A<X,&array> { }; // error
?end example]

However, I somewhat fail to see how this applies in the case above since the
member template range does not seem to violate the restriction from
14.5.4/9. In particular, a non-member template version

typedef int Enum;

template < Enum first, Enum last >
struct range {

range<first+1,last> data;

};// range

template < Enum val >
struct range<val,val> {};

is fine.

I also considered whether there might some language in the standard that
implies that in

recursive_type<some_type>::range<1,20>

"eval" would be a template parameter of the member template range (because
that seems to be Comeaus's point of view), however, I did not find
something like that. Or is there something else in the standard that I am
missing here?



Thanks

Kai-Uwe Bux
 
G

Greg

Kai-Uwe Bux said:
Hi folks,


I would like to know which clause of the standard rules out this:

template < typename eval >
struct recursive_template {

typedef typename eval::enum_type Enum;

template < Enum first, Enum last >
struct range {

range<first+1,last> data;

};// range

template < Enum val > // line 13
struct range<val,val> {};

}; // recursive_template


Comeau rejects this code saying:

Comeau C/C++ 4.3.3 (Aug 6 2003 15:13:37) for ONLINE_EVALUATION_BETA1
Copyright 1988-2003 Comeau Computing. All rights reserved.
MODE:strict errors C++

"ComeauTest.c", line 13: error: the type of partial specialization template
parameter constant "val" depends on another template parameter
template < Enum val >
^

I found [14.5.4/9]:

... - The type of a template parameter corresponding to a specialized
non-type argument shall not be dependent on a parameter of the
specialization. [Example:
template <class T, T t> struct C {};
template <class T> struct C<T, 1>; // error
template< int X, int (*array_ptr)[X] > class A {};
int array[5];
template< int X > class A<X,&array> { }; // error
?end example]

However, I somewhat fail to see how this applies in the case above since the
member template range does not seem to violate the restriction from
14.5.4/9. In particular, a non-member template version

typedef int Enum;

template < Enum first, Enum last >
struct range {

range<first+1,last> data;

};// range

template < Enum val >
struct range<val,val> {};

is fine.

I also considered whether there might some language in the standard that
implies that in

recursive_type<some_type>::range<1,20>

"eval" would be a template parameter of the member template range (because
that seems to be Comeaus's point of view), however, I did not find
something like that. Or is there something else in the standard that I am
missing here?

gcc 4.01 reports no comparable error. Instead, the program fails to
complie because the range class template recurses forever. The
range<val,val> specialization does not stop the recursion, at least
when val is a non-type parameter. I have found that wrapping an integer
in a type usually works in such situations. Something like:

template <int I>
struct Integer
{
typedef Integer<I+1> next;
};

To "increment" this type, simply refer to Integer<N>::next .

Greg
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top