代码之家  ›  专栏  ›  技术社区  ›  greywolf82

模板基类中的重载运算符

  •  1
  • greywolf82  · 技术社区  · 6 年前

    我有以下代码:

    #include <iostream>
    #include <cstring>
    
    #define THIS(X) static_cast<X*>(this)
    
    template<typename T>
    class Base {
    public:
        Base() {
        }
        virtual ~Base() {
        }
        void foo() {
            THIS(T)->a[0] = 1;
        }
        T& operator=(const T& o) {
            std::cout <<"operator="<<std::endl;
            memcpy(THIS(T)->a, o.a, THIS(T)->size);
            return static_cast<T&>(*this);
        }
    };
    
    template<typename T>
    class Der1: public Base<Der1<T> > {
    private:
        T* a;
        unsigned int size;
    public:
        Der1(int d) {
            a = new T[d];
            size = d;
        }
        virtual ~Der1() {
            delete[] a;
        }
        using Base<Der1<T> >::operator=;
        friend class Base<Der1<T> > ;
    };
    
    template<typename T, unsigned int EL>
    class Der2: public Base<Der2<T, EL> > {
    private:
        T a[EL];
        unsigned int size;
    public:
        Der2() {
            size = EL;
        }
        virtual ~Der2() {
        }
        using Base<Der2<T, EL> >::operator=;
        friend class Base<Der2<T, EL> > ;
    };
    
    int main() {
        Der1<double> a(5);
        Der2<double, 10> b;
        a.foo();
        b.foo();
        Der2<double, 10> c;
        Der1<double> d(5);
        c = b;
        a = d;
        return 0;
    }
    

    编译时收到以下错误:

    g++ -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"main.d" -MT"main.o" -o "main.o" "../main.cpp"
    ../main.cpp: In function ‘int main()’:
    ../main.cpp:48:7: error: ‘constexpr Der2<double, 10>& Der2<double, 10>::operator=(const Der2<double, 10>&)’ cannot be overloaded
     class Der2: public Base<Der2<T, EL> > {
           ^~~~
    ../main.cpp:23:5: error: with ‘T& Base<T>::operator=(const T&) [with T = Der2<double, 10>]’
      T& operator=(const T& o) {
         ^~~~~~~~
    ../main.cpp:31:7: error: ‘constexpr Der1<double>& Der1<double>::operator=(const Der1<double>&)’ cannot be overloaded
     class Der1: public Base<Der1<T> > {
           ^~~~
    ../main.cpp:23:5: error: with ‘T& Base<T>::operator=(const T&) [with T = Der1<double>]’
      T& operator=(const T& o) {
         ^~~~~~~~
    make: *** [subdir.mk:20: main.o] Error 1
    

    virtual 在模板基类中 operator= 然后它编译了,但是我看不到任何输出,所以我没有调用正确的方法。

    1 回复  |  直到 6 年前
        1
  •  1
  •   Evg    6 年前

    奇怪的是,clang接受了你的代码。这在gcc和clang中都有效:

    Base& operator=(const Base& o) {
        std::cout << "operator=" << std::endl;
        memcpy(self().a, o.self().a, self().size);
        return *this;
    }
    
    T& self() {
        return static_cast<T&>(*this);
    }
    
    const T& self() const {
        return static_cast<const T&>(*this);
    }
    

    顺便说一句,a virtual 析构函数在这里看起来很奇怪:您混合了编译时多态性(通过CRTP)和运行时多态性(通过CRTP) 事实上的

    编辑。

    Der& operator=(const Der& o)
    {
        Base<Der...>::operator=(o);
        return *this;
    }