如果为B的实例调用移动分配,则以下类层次结构将在GCC中引起[-Wvirtual-move-assign]警告。
struct A {
std::vector<int> v;
};
struct B : public virtual A {};
以下情况确实导致发生警告
/*** SCENARIO 1 ***/
class C {
B a;
public:
void foo(B& b) {
b = a; // warning
// or
a = b; // warning
}
};
/*** SCENARIO 2 ***/
void foo(const B& a, B& b) {
b = a; // warning
}
int main() {
/*** SCENARIO 3 ***/
B b;
std::vector<B> v1;
v1.push_back(b); // warning
/*** SCENARIO 4 ***/
B b1;
B b2;
b1 = b2; // warning
/*** SCENARIO 5 ***/
B b3;
b3 = B(); // warning
}
即使稍后再次使用从对象分配的警告,仍然会发生警告。除了方案5涉及右侧的右值并因此涉及到移动分配之外,我希望(并且确实是我想要)在这些情况下发生复制分配,而不是移动分配。如果是这样,那么为什么会发生此警告?动作实际发生在表达式中的某处吗?
似乎您误报了。对Why does gcc warn about calling a non-trivial move assignment operator with std::tuple and virtual inheritance?的答案表明,gcc发出此警告的次数比实际需要的要多,而clang则不会。因此,我加强了您的示例(如该答案中所做的那样),并将其交给了clang。
struct A {
std::vector<int> v;
};
struct AA : public virtual A {};
struct AB : public virtual A {};
struct B : public AA, AB {};
[使用此设置,叮当声仅针对b3 = B();
行发出警告(方案5)。它接受其他情况,表明gcc只是偏执。 (要么是gcc发出了误报,要么是clang出现了错误。不过,您的分析似乎是正确的,因此前者很可能如此。)