If I want to specialise just one method in a template, how do I do it?

前端 未结 4 1276
青春惊慌失措
青春惊慌失措 2020-11-30 09:54

Say I have a templated class like

template  struct Node
{
    // general method split
    void split()
    {
        // ... actual code her         


        
相关标签:
4条回答
  • 2020-11-30 10:07

    Your case is a fortunate example because you are fully-specializing the template. In other words there is only one template argument, and for the function you wish to specialize, you are providing a fully-specialized instantiation of that function definition. Unfortunately for partial class template specialization, it is a requirement that you re-implement the class.

    For example, this works:

    template<typename T, typename U>
    struct Node
    {
        void function() { cout << "Non-specialized version" << endl; }
    };
    
    template<>
    void Node<int, char>::function() { cout << "Specialized version" << endl; }
    

    The partially specialized version though will not work:

    template<typename T, typename U>
    struct Node
    {
        void function() { cout << "Non-specialized version" << endl; }
    };
    
    template<typename U>
    void Node<int, U>::function() { cout << "Specialized version" << endl; }
    

    What you may want to-do if you find yourself in the second scenario, in order to avoid the needless duplication of code, is pack all the common elements into a common base-class, and then place all the elements that will be varying with the partial specialization in a derived class. That way you do not need to reduplicate all the common code in the base-class, you would only need to re-write the definitions for the specialized derived class.

    0 讨论(0)
  • 2020-11-30 10:28

    Awkward method that I usually use: Declare a "basic" template implementation. Then declare your template implementation, the default implementation would just inherit the "basic" one. The customize would inherit the "basic", plus override specific methods. Like this:

    template <typename T> struct NodeBase
    {
        // methods
    };
    
    template <typename T> struct Node
        :public NodeBase<T>
    {
        // nothing is changed
    };
    
    template <> struct Node<SpecificType>
        :public NodeBase<SpecificType>
    {
        // re-define methods you want
    };
    

    Note that the "method overriding" has nothing to do with virtual functions or etc. It's just a declaring a function with the same name and parameters as in the base - the compiler will automatically use it.

    0 讨论(0)
  • 2020-11-30 10:30

    You can provide a specialization for only that function outside the class declaration.

    template <typename T> struct Node
    {
        // general method split
        void split()
        {
            // implementation here or somewhere else in header
        }
    };
    

    // prototype of function declared in cpp void splitIntNode( Node & node );

    template <>
    void Node<int>::split()
    {
         splitIntNode( this ); // which can be implemented
    }
    
    int main(int argc, char* argv[])
    {
       Node <char> x;
       x.split(); //will call original method
       Node <int> k;
       k.split(); //will call the method for the int version
    }
    

    If splitIntNode needs access to private members, you can just pass those members into the function rather than the whole Node.

    0 讨论(0)
  • 2020-11-30 10:32

    Just define some

    template<>
    void Node<Triangle*>::split()
    {
    }
    

    after the primary template, but before the first time you ever instantiate it.

    0 讨论(0)
提交回复
热议问题