Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Template parameters not used in partial specialization when usingtypedefined

Reply
Thread Tools

Template parameters not used in partial specialization when usingtypedefined

 
 
jrwats
Guest
Posts: n/a
 
      07-11-2009
class Nil { };

template<class H, class T>
struct TypeList
{
typedef H Head;
typedef T Tail;
};

template
<class T01=Nil, class T02=Nil, class T03=Nil, class T04=Nil, class
T05=Nil,
//...
>

struct Seq;

template<class T01>
struct Seq<T01>
{
typedef TypeList<T01, Nil > Type;
};

template <typename R, class TList> class FunctorImpl;

// OK, finally the interesting bit. The below will error with:
// error: template parameters not used in partial specialization: P1
//
template <class R, class P1>
class FunctorImpl<R, typename Seq<P1>::Type >
{
public:
typedef R ResultType;
typedef P1 Parm1;
virtual R operator()(Parm1) = 0;
};

// This of course works:
//
template <class R, class P1>
class FunctorImpl<R, TypeList<P1, Nil> >
{
public:
typedef R ResultType;
typedef P1 Parm1;
virtual R operator()(Parm1) = 0;
};

// The motivation for this is I'd like to ultimate (instead of Seq)
// use the Function Signature specialization trick:

template <class Fun> struct Cons;

template <class T1> struct Cons<void (*)(T1)>
{
typedef TypeList<T1, Nil> Type;
};

template <class T1, class T2>
struct Cons<void (*)(T1, T2)>
{
typedef TypeList<T1, TypeList<T2, Nil> > Type;
};

//...

#define MakeTL(...) Cons< void (*) (__VA_ARGS__) >::Type

template <class R, class P1>
class FunctorImpl<R, typename MakeTL(P1) >
{
public:
typedef R ResultType;
typedef P1 Parm1;
virtual R operator()(Parm1) = 0;
};

But this fails for the same reason "class FunctorImpl<R, typename
Seq<P1>::Type >" fails.

Is there any way around this? This seems like it should be valid C+
+... but this appears to be compiler independent.
 
Reply With Quote
 
 
 
 
Alf P. Steinbach
Guest
Posts: n/a
 
      07-11-2009
* jrwats:
> class Nil { };
>
> template<class H, class T>
> struct TypeList
> {
> typedef H Head;
> typedef T Tail;
> };
>
> template
> <class T01=Nil, class T02=Nil, class T03=Nil, class T04=Nil, class
> T05=Nil,
> //...
> >

> struct Seq;
>
> template<class T01>
> struct Seq<T01>
> {
> typedef TypeList<T01, Nil > Type;
> };
>
> template <typename R, class TList> class FunctorImpl;
>
> // OK, finally the interesting bit. The below will error with:
> // error: template parameters not used in partial specialization: P1
> //
> template <class R, class P1>
> class FunctorImpl<R, typename Seq<P1>::Type >
> {
> public:
> typedef R ResultType;
> typedef P1 Parm1;
> virtual R operator()(Parm1) = 0;
> };


I think this is similar to how such an indirect (dependent) type cannot be
deduced for a function argument. The compiler's problem is, given some use of
FunctorImpl<X,Y>, find out if it matches the above with R=X and P1 some unique
type such that Seq<P1>::Type = Y. Uhm, deducing P1 from Y is rather difficult...

I guess you're thinking from the perspective of sort of handing in P1 and get
out Seq<P1>::Type.

The compiler, however, must work in the opposite direction: for any concrete use
of FunctorImpl it's handed some type Y, which it (if it accepted the code above)
would have to match against all possible Type in Seq<P1>::Type for all possible
P1, to find the presumably unique type P1.


> // This of course works:
> //
> template <class R, class P1>
> class FunctorImpl<R, TypeList<P1, Nil> >
> {
> public:
> typedef R ResultType;
> typedef P1 Parm1;
> virtual R operator()(Parm1) = 0;
> };


Yes. Given use of FunctorImpl<X, Y>, the compiler matches X to R, and Y to
TypeList<P1, Nil>, that is, Y must be a type of that form, from which P1 follows.


>
> // The motivation for this is I'd like to ultimate (instead of Seq)
> // use the Function Signature specialization trick:
>
> template <class Fun> struct Cons;
>
> template <class T1> struct Cons<void (*)(T1)>
> {
> typedef TypeList<T1, Nil> Type;
> };
>
> template <class T1, class T2>
> struct Cons<void (*)(T1, T2)>
> {
> typedef TypeList<T1, TypeList<T2, Nil> > Type;
> };
>
> //...
>
> #define MakeTL(...) Cons< void (*) (__VA_ARGS__) >::Type
>
> template <class R, class P1>
> class FunctorImpl<R, typename MakeTL(P1) >
> {
> public:
> typedef R ResultType;
> typedef P1 Parm1;
> virtual R operator()(Parm1) = 0;
> };
>
> But this fails for the same reason "class FunctorImpl<R, typename
> Seq<P1>::Type >" fails.
>
> Is there any way around this? This seems like it should be valid C+
> +... but this appears to be compiler independent.


Uhm, I think macros...


Cheers & hth.,

- Alf
 
Reply With Quote
 
 
 
 
jrwats
Guest
Posts: n/a
 
      07-11-2009
On Jul 11, 12:34*pm, "Alf P. Steinbach" <(E-Mail Removed)> wrote:
>
> I think this is similar to how such an indirect (dependent) type cannot be
> deduced for a function argument. The compiler's problem is, given some use of
> FunctorImpl<X,Y>, find out if it matches the above with R=X and P1 some unique
> type such that Seq<P1>::Type = Y. Uhm, deducing P1 from Y is rather difficult...
>
> I guess you're thinking from the perspective of sort of handing in P1 and get
> out Seq<P1>::Type.
>
> The compiler, however, must work in the opposite direction: for any concrete use
> of FunctorImpl it's handed some type Y, which it (if it accepted the code above)
> would have to match against all possible Type in Seq<P1>::Type for all possible
> P1, to find the presumably unique type P1.
>
> > // This of course works:
> > //
> > template <class R, class P1>
> > class FunctorImpl<R, TypeList<P1, Nil> >
> > {
> > public:
> > * * typedef R ResultType;
> > * * typedef P1 Parm1;
> > * * virtual R operator()(Parm1) = 0;
> > };

>
> Yes. Given use of FunctorImpl<X, Y>, the compiler matches X to R, and Y to
> TypeList<P1, Nil>, that is, Y must be a type of that form, from which P1 follows.
>


Ahh... wasn't thinking about what the compiler had to do... this makes
sense.

> Uhm, I think macros...


Yeah... That's how the Loki library (haven't looked at what Boost
does) does it. It defines a bunch of macros for typelists, but also
just specializes FunctorImpl on Seq itself:

template <class R, class P1>
class FunctorImpl<R, Seq<P1> >
{
public:
typedef R ResultType;
typedef P1 Parm1;
virtual R operator()(Parm1) = 0;
};

You can't pass in a TypeList to FunctorImpl (in this specialization)
but you potentially have access to a TypeList (in FunctorImpl's code)
via Seq::Type.
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Template specialization (not partial): what is it? Markus C++ 2 12-11-2011 03:09 PM
Template template partial specialization Hizo C++ 17 03-07-2011 08:09 AM
how to do partial specialization template for non member method template vj C++ 1 12-20-2010 11:57 AM
syntax problem for partial template specialization for a template class. toton C++ 1 12-28-2006 04:08 PM
Template specialization for templated and primitive type template parameters case2005 C++ 3 02-13-2005 06:53 PM



Advertisments