Reputation: 5809
I'd appreciate help figuring out what going on in this problem that's come up in my code which I've reduced to the following:
typedef unsigned short ushort;
template<typename T = ushort*>
struct Foo
{
};
// Specialization -- works when not a specialization
template<
template<typename,typename> class Container ,
template<typename , template<typename,typename> class> class MetaFunction
>
struct Foo<Container<ushort,typename MetaFunction<ushort,Container>::Type> >
{
//typedef Container<ushort,typename MetaFunction<ushort,Container>::Type> TestType; // OK
};
int main()
{
}
On compilation (gcc 5.4.0) I get the error:
Test.cpp:14:8: error: template parameters not deducible in partial specialization:
struct Foo<Container<ushort,typename MetaFunction<ushort,Container>::Type> >
^
Test.cpp:14:8: note: ‘template<class, template<class, class> class<template-parameter-2-2> > class MetaFunction’
Oddly, the argument Container<ushort,typename MetaFunction<ushort,Container>::Type>
to the specialization appears to be valid.
Upvotes: 7
Views: 4121
Reputation: 2077
In C++20 there's type_identity which you can use for this purpose.
Upvotes: 0
Reputation: 56547
The problem here is that
MetaFunction<ushort,Container>::Type
is a non-deduced context, in other words the compiler cannot deduce the template arguments from it, so your specialization is not valid. To see why, read more about it from a previous SO question
Basically a non-deduced context boils down to
template<typename T>
struct Identity
{
using type = T;
};
Now in a pattern like Identity<T>::type
, T
won't be deduced, although for you it may look obvious (see again the examples in the link I provided for why this is so, it has to do with partial specializations and lack of 1-1 correspondence between types and the members of the specialization).
Upvotes: 10