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