具有多重继承的复制赋值运算符

pre*_*eys 2 c++ inheritance templates assignment-operator c++11

下面我的复制构造函数工作正常,但我不明白我的复制赋值运算符有什么问题.

#include <iostream>

template <typename... Ts> class foo;

template <typename Last>
class foo<Last> {
    Last last;
public:
    foo (Last r) : last(r) { }
    foo() = default;
    foo (const foo& other) : last(other.last) { }

    foo& operator= (const foo& other) {
        last = other.last;
        return *this;
    }
};

template <typename First, typename... Rest>
class foo<First, Rest...> : public foo<Rest...> {
    First first;
public:
    foo (First f, Rest... rest) : foo<Rest...>(rest...), first(f) { }
    foo() = default;
    foo (const foo& other) : foo<Rest...>(other), first(other.first) { std::cout << "[Copy constructor called]\n"; }

    foo& operator= (const foo& other) {  // Copy assignment operator
        if (&other == this)
            return *this;
        first = other.first;
        return foo<Rest...>::operator= (other);
    }
};

int main() {
    const foo<int, char, bool> a(4, 'c', true);
    foo<int, char, bool> b = a;  // Copy constructor works fine.
    foo<int, char, bool> c;
//  c = a;  // Won't compile.
}
Run Code Online (Sandbox Code Playgroud)

错误信息:

error: invalid initialization of reference of type 'foo<int, char, bool>&' from expression of type 'foo<char, bool>'
         return foo<Rest...>::operator= (other);
                                              ^
Run Code Online (Sandbox Code Playgroud)

有人能在这里指出问题吗?

Sto*_*ica 8

你的退货声明

return foo<Rest...>::operator= (other);
Run Code Online (Sandbox Code Playgroud)

返回a foo<Rest...>(operator=定义的引用类型).但它是由一个应该返回的运营商这样做的foo<First, Rest...>&.

从本质上讲,你返回Base,其中一个Derived&参考的预期.引用根本不会绑定.

幸运的是,修复很简单:不返回结果foo<Rest...>::operator=,*this而是返回.

foo& operator= (const foo& other) {  // Copy assignment operator
    if (&other == this)
        return *this;
    first = other.first;
    foo<Rest...>::operator= (other);
    return *this;
}
Run Code Online (Sandbox Code Playgroud)