Would any one knows according to what rules code below doesn\'t compile?
template
struct B
{
typedef T type;
};
template
Assuming you already added typename
as suggested by Nawaz.
The problem is exactly explained in the error message you encounter: "template parameter is not deducible in partial specialization B
. The problem is that B
and T
is exactly the same for all types T
. Consider the following example:
class MyClass1 {};
typedef typename B::type MyClass2; //(*)
X obj1;
X obj2;
The result of line (*)
is a type MyClass2 which is essentially MyClass1
. So, obj1
and obj2
should be objects of the same class. Now, which version of template X
should they use?
If you would expect the specialised version of X
, tell me if the answer should be the same if line (*)
is removed (and obviously obj2
as well). Still obj1
should be the specialised version of X
as line (*)
has nothing to do with it.
But now we expect the compiler to detect that some type can be potentially declared as B
although we never do this. We expect the compiler to verify all possible template instantiations to check if there is no strange typedef in one of them.
I hope this clarifies why such specialisation cannot be handled by the compiler.
An alternative that might help
I believe your problem could be attacked by creating a trait class for explicitly marking types that should be handled in a special way. Something like this:
template
struct boolean_value {
static const bool value=v;
};
template
struct is_my_interesting_type : public boolean_value {};
class MyClass {
...
};
template <>
struct is_my_interesting_type : public boolean_value {};
template
class InternalX {
... //generic version of your template X
};
template
class InternalX {
... //special version of your template X
};
template
class X : public InternalX::value> {};
Also, you might be interesting how it is done in boost library, in particular Boost.Type_Traits