Re: Template parameters not used in partial specialization when using
typedefined
* 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