Template partial specialization

后端 未结 3 1834
不知归路
不知归路 2020-12-11 08:47

Would any one knows according to what rules code below doesn\'t compile?

template 
struct B
{
    typedef T type;
};

template

        
3条回答
  •  抹茶落季
    2020-12-11 09:11

    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::type*. The problem is that B::type 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::type 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

提交回复
热议问题