C++ template class specialization: why do common methods need to be re-implemented

后端 未结 5 786
心在旅途
心在旅途 2021-02-19 06:32

In the sample:

#include 

using namespace std;

class B
{
public:
    virtual void pvf() = 0;
};

template 
class D : public B
{
p         


        
相关标签:
5条回答
  • 2021-02-19 07:01

    Consider that D<T>::D() will be responsible for default-constructing string data, and that D<bool> doesn't have any such member. Clearly there is no way to use the same emitted code in each case.

    However, if your default constructor doesn't do anything (in either version here), just omit it and allow the compiler to do the work.

    0 讨论(0)
  • 2021-02-19 07:11

    Each specialisation of a class template gives a different class - they do not share any members with each other. Since you've explicitly specialised the entire class, you don't get any of the members from the template, and must implement them all.

    You can explicitly specialise individual members, rather than the entire class:

    template <> void D<bool>::pvf(){ cout << "bool type" << endl; }
    

    Then D<bool> will still contain all the members of the class template that you haven't explicitly specialised, including the default constructor.

    0 讨论(0)
  • 2021-02-19 07:19

    You need to reimplement it because D<T> and D<bool> are totally unrelated classes (they just happen to "share the name"). That's just how templates work.

    If you want the classes to share construction code, just put that code inside B::B (i.e. the same thing you do every time you want to reuse code in different branches of the same hierarchy: move the code up and let inheritance handle the rest).

    0 讨论(0)
  • 2021-02-19 07:20

    No, there is not.

    Specialization is behaving very differently than inheritence. It has no connection to the generic template version.

    When you use/instantiate a template, the compiler will create a new type name, and then look for how this type is defined. When it finds a specialization, then it takes that as the definition for the new type. When it does not, it takes the generic template and instantiates it.

    Therefore they have no connection, and you are just writing an entirely new class, just with a special name for the compiler to find in case of someone using/instantiating the template to find it under that name.

    0 讨论(0)
  • 2021-02-19 07:27

    The problem is your erroneous assumption that there is anything common between D<A> and D<B>. Template instances are types, and two different instances are two different types, end of story. It only so happens that instances of the same template have formally similar code, but with specialization you can define any type you like. In short, every type that you define explicitly is entirely independent, and there is no commonality across specialized template instances, even if they happen to have the same name.

    For example:

    template <typename T> struct Foo
    {
        T & r;
        const T t;
        void gobble(const T &);
        Foo(T *);
    };
    
    template <> struct Foo<int>
    {
        std::vector<char> data;
        int gobble() const;
        Foo(bool, int, Foo<char> &);
    };
    

    The types Foo<char> and Foo<int> have nothing to do with one another, and there is no reason why any part of one should have any use inside the other.

    If you want to factor out common features, use private inheritance:

    template <typename> struct D : private DImpl { /* ... */ }
    
    0 讨论(0)
提交回复
热议问题