C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Partial specialization of non-type template arguments

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated)
View previous topic :: View next topic  
Author Message
Motti Lanzkron
Guest





PostPosted: Wed Dec 29, 2004 9:43 pm    Post subject: Partial specialization of non-type template arguments Reply with 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 <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





PostPosted: Thu Dec 30, 2004 3:13 am    Post subject: Re: Partial specialization of non-type template arguments Reply with quote



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





PostPosted: Thu Dec 30, 2004 9:54 am    Post subject: Re: Partial specialization of non-type template arguments Reply with quote



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





PostPosted: Thu Dec 30, 2004 8:15 pm    Post subject: Re: Partial specialization of non-type template arguments Reply with quote

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





PostPosted: Thu Dec 30, 2004 8:37 pm    Post subject: Re: Partial specialization of non-type template arguments Reply with quote

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





PostPosted: Fri Dec 31, 2004 1:19 pm    Post subject: Re: Partial specialization of non-type template arguments Reply with quote

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





PostPosted: Mon Jan 03, 2005 12:36 am    Post subject: Re: Partial specialization of non-type template arguments Reply with quote

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
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated) All times are GMT
Page 1 of 1

 
Jump to:  
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


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.