 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Motti Lanzkron Guest
|
Posted: Wed Dec 29, 2004 9:43 pm Post subject: Partial specialization of non-type template arguments |
|
|
I'm trying to specialize a template according to a non-type argument
which is dependant on another template argument. None of the compilers
I tried it on gave the results I expected but I can't find anything
against it in the standard.
Here's a contrived example of what I'm trying to do:
template <int N>
struct Int {
static const int value = N;
};
template <class T, int N>
struct Eq {
static const bool value = false;
};
template <class T>
struct Eq<T, T::value> {
static const bool value = true;
};
bool check = Eq<Int<2>, 2>::value;
Here's the message I get from Comeau online:
"ComeauTest.c", line 12: error: a partial specialization nontype
argument must be the name of a nontype parameter or a constant
struct Eq<T, T::value> {
^
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Hyman Rosen Guest
|
Posted: Thu Dec 30, 2004 3:13 am Post subject: Re: Partial specialization of non-type template arguments |
|
|
Motti Lanzkron wrote:
| Quote: | I can't find anything against it in the standard.
|
You didn't look hard enough: 14.5.4/9
A partially specialized non-type argument expression
shall not involve a template parameter of the partial
specialization except when the argument expression is
a simple _identifier_.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Manuel Petit Guest
|
Posted: Thu Dec 30, 2004 9:54 am Post subject: Re: Partial specialization of non-type template arguments |
|
|
Motti Lanzkron wrote:
| Quote: | I'm trying to specialize a template according to a non-type argument
which is dependant on another template argument. None of the compilers
I tried it on gave the results I expected but I can't find anything
against it in the standard.
Here's a contrived example of what I'm trying to do:
template <int N
struct Int {
static const int value = N;
};
template
struct Eq {
static const bool value = false;
};
template
struct Eq
static const bool value = true;
};
|
Why write that when you can simply write:
template <class T, int N>
struct Eq {
static bool const value = N==T::value;
};
manuel,
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Graeme Prentice Guest
|
Posted: Thu Dec 30, 2004 8:15 pm Post subject: Re: Partial specialization of non-type template arguments |
|
|
On 30 Dec 2004 04:54:44 -0500, Manuel Petit wrote:
| Quote: | Motti Lanzkron wrote:
I'm trying to specialize a template according to a non-type argument
which is dependant on another template argument. None of the compilers
I tried it on gave the results I expected but I can't find anything
against it in the standard.
Here's a contrived example of what I'm trying to do:
template <int N
struct Int {
static const int value = N;
};
template
struct Eq {
static const bool value = false;
};
template
struct Eq
static const bool value = true;
};
Why write that when you can simply write:
template <class T, int N
struct Eq {
static bool const value = N==T::value;
};
|
I wondered that to start with, then I realized the intention could be
that when the Eq template is used like this
Eq
the specialization is wanted if somevalue is the same value as the
sometype::value, otherwise the primary template. If that's the case,
this can be achieved by inheriting one of two base classes where the
base class is selected something like this
template <class T, int N>
struct Eq : public somebase<T,T::value==N> {
};
except that if T doesn't have a suitable value member the code fails.
There's a chance it's possible to deal with this by using SFINAE so just
for fun, I tried but GCC complains for the following code if the lines
in main involving s2,s3 are uncommented whereas Comeau and VC7.1 are ok
with all of it.
The C++ standard SFINAE rules don't appear to allow the case of
template <typename T1>
yes & f1( typename x1<T1::value>::type *);
when T1::value is not being used as a type but Comeau, VC7.1 and GCC all
give no error if T1 has no value member.
#include <iostream>
#include <ostream>
template <int n>
struct x1
{
typedef int type;
};
typedef char yes;
typedef char no[2];
template <typename T1>
yes & f1( typename x1<T1::value>::type *);
template <typename T1>
no &f1(...);
struct s1 {
static const int value = 16;
};
struct s2 {
int * value;
};
struct s3 {
void value();
};
struct s4 {};
template <typename T, int N, bool b>
struct helper1 {
// has no value member matching N
static const bool result = false;
};
template <typename T, int N,bool b>
struct helper2_has_value_integral_const_member : helper1<T,N,false> {
};
template <typename T, int N>
struct helper2_has_value_integral_const_member<T,N,true> {
// has value member equal to N
static const bool result = true;
};
template <typename T, int N>
struct helper1<T,N,true> :
public helper2_has_value_integral_const_member
<T,N,T::value == N> {};
template <class T, int N>
struct Eq : public helper1<T,N,sizeof(f1 {
};
int main()
{
std::cout << (sizeof(f1
// << (sizeof(f1
// << (sizeof(f1
<< (sizeof(f1
<< Eq
<< Eq
// << Eq
// << Eq
<< Eq
}
Graeme
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Motti Lanzkron Guest
|
Posted: Thu Dec 30, 2004 8:37 pm Post subject: Re: Partial specialization of non-type template arguments |
|
|
Hyman Rosen wrote:
| Quote: | Motti Lanzkron wrote:
I can't find anything against it in the standard.
You didn't look hard enough: 14.5.4/9
A partially specialized non-type argument expression
shall not involve a template parameter of the partial
specialization except when the argument expression is
a simple _identifier_.
|
Right you are, and when I tried even harder I found that this has been
discussed in the past (I hope this link works):
http://groups.google.co.uk/groups?hl=en&lr=&threadm=us5snlond4or58%40corp.supernews.com
I see Rani Sharoni suggested using Int2Type type parameter instead of
the int non-type parameter (in my contrived example this is obviously
ludicrous but it fits the real problem I had). So it seems clear that
there is no real technical difficulty that makes 14.5.4/9 necessary.
Why is it there then?
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Hyman Rosen Guest
|
Posted: Fri Dec 31, 2004 1:19 pm Post subject: Re: Partial specialization of non-type template arguments |
|
|
Motti Lanzkron wrote:
| Quote: | Why is it there then?
|
Let's modify your code slightly:
template <int N> struct Int { static const int value = N; };
template <int N> struct Eq { static const bool value = false; };
template <class T> struct Eq<T::value> { static const bool value = true; };
bool check = Eq<2>::value;
See?
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Motti Lanzkron Guest
|
Posted: Mon Jan 03, 2005 12:36 am Post subject: Re: Partial specialization of non-type template arguments |
|
|
Hyman Rosen wrote:
| Quote: | Motti Lanzkron wrote:
Why is it there then?
Let's modify your code slightly:
template <int N> struct Int { static const int value = N; };
template <int N> struct Eq { static const bool value = false; };
template <class T> struct Eq<T::value> { static const bool value = true; };
bool check = Eq<2>::value;
See?
|
Nope sorry, I'm completely devoid of sight.
I don't understand what you're trying to show with your example.
In any case how is it different from:
template <class T> struct Type { typedef T type; };
template <class T> struct Eq { static const bool value = false; };
template <class T> struct Eq<typename T::type>
{ static const bool value = true; };
bool check = Eq<2>::value;
This isn't legal either but you don't say that during specialization a
template type parameter must be a simple identifier.
I don't understand why the restriction in case of non-type parameters
is necessary. It seems that in every case there is a type equivalent
that is legal which means that the compiler could save us from the
proverbial extra level of indirection.
Consider the following:
// class with static buffer
struct Stat {
static char buf;
};
char Stat::buf;
#ifdef WHAT_I_EXPECT_TO_WORK
template <class T, char* P>
struct Test
{
static const bool value = false;
};
template <class T>
struct Test_<T, &T::buf>
{
static const bool value = true;
};
#else // !WHAT_I_EXPECT_TO_WORK
// Wrap a pointer to char with a type
template <char* P> struct Wrap {};
// extra level of indirection
template <class T, class Y>
struct Test_
{
static const bool value = false;
};
template <class T>
struct Test_<T, Wrap<&T::buf> >
{
static const bool value = true;
};
template <class T, char* P>
struct Test : Test_<T, Helper {};
char test1[Test<Stat, &Stat::buf>::value]; // OK
char test2[Test<int, &Stat::buf>::value]; // Error zero sized array
#endif
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|