为什么我的赋值运算符不被调用?

Meh*_*dad 1 c++ operator-overloading assignment-operator

我很困惑......为什么我的任务操作员不会在这里被调用?

template<typename This>
struct mybase
{
    This& operator =(const This &other)
    {
        __debugbreak();  // The debugger should break here, but doesn't.
        return static_cast<This &>(*this):
    }
};

struct myderived : mybase<myderived>
{
    int x;
};

int main()
{
    myderived a = myderived();  // And yes, I know it's redundant...
    myderived b = myderived();
    a = b;

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

Ton*_*ion 6

因为derived中的默认赋值运算符将隐藏重载的基数.


Che*_*Alf 5

mybase::operator=隐藏通过自动生成的拷贝赋值运算符myderived::operator=.

您可以使用using声明使派生类中的基类操作符可见.

编辑:每个请求添加示例:

template<typename This>
struct mybase
{
    This& operator =(const This &other)
    {
        //__debugbreak();  // The debugger should break here, but doesn't.
        return static_cast<This &>(*this);
    }
};

struct myderived : mybase<myderived>
{
    using mybase<myderived>::operator=;
    int x;
};

int main()
{
    myderived a = myderived();  // And yes, I know it's redundant...
    myderived b = myderived();
    a = b;
}
Run Code Online (Sandbox Code Playgroud)

这与Visual C++ 10.0和Comeau Online编译良好.实际上,后者意味着它是很好的标准C++.但是,代码不能使用MinGW g ++ 4.4.1(编译器错误)进行编译.

编辑2:实际上,现在检查,使用Visual C++ 10.0编译,但不调用基类操作符.所以也许g ++是正确的.using通常是引入基类赋值运算符(或其他)的方法,但在这种情况下,它与派生类的副本赋值运算符具有相同的签名,我还不知道Visual C++行为是否正确 - 这是语言的一个角落.

编辑3:我检查了N3290(标准草案与C++ 11相同),它说

§12.8/ 18:
如果类定义没有显式声明一个复制赋值运算符,则会隐式声明一个.如果类定义声明了移动构造函数或移动赋值运算符,则隐式声明的复制赋值运算符被定义为已删除; 否则,它被定义为默认值(8.4).

我个人解释说,随着using声明到位,类"声明"一个复制赋值运算符,因此不应该隐式生成(因为它似乎是Visual C++ 10.0).但是,这是该语言的一个极端情况.其他人可能会对此有不同的解释,如上所述,编译器也有所不同!

干杯&hth.,