重载赋值运算符和零规则

Urw*_*ald 4 c++ overloading operators

我已经编写了一个模板类A<T>,并且正在利用零规则(我让编译器生成析构函数、复制/移动构造函数和赋值运算符重载)。但是,我现在需要一个自定义的赋值运算符,它采用不同的类型B<T>作为参数:

A<T>& operator=(const B<T>& rhs);
Run Code Online (Sandbox Code Playgroud)

此实现会阻止编译器生成默认析构函数等吗?我的猜测是否定的,因为编译器生成

A<T>& operator=(const A<T>& rhs);
Run Code Online (Sandbox Code Playgroud)

这与我想要实现的重载完全不同。

woh*_*tad 5

根据我的理解,添加operator=重载并不会阻止编译器按照0的规则生成默认的。

我的这种理解基于这样一个事实:您的operator=重载实际上不是复制分配也不是移动分配
因此,关于生成默认构造函数和赋值运算符的规则是不相关的

我用MSVC验证过。

您可以使用下面的代码来验证您的编译器:

#include <iostream>

template <typename T>
struct B
{
    B(T const & n) : bn(n) {}
    T bn{ 0 };
};

template <typename T>
struct A
{
    A(T const & n) : an(n) {}
    A<T>& operator=(const B<T>& rhs)
    {
        an = rhs.bn;
        return *this;
    }
    T an{ 0 };
};

int main()
{
    A<int> a1{ 5 };
    A<int> a2{ 6 };
    std::cout << a2.an << ",";
    a2 = a1;    // Use default assinment
    std::cout << a2.an << ",";
    B<int> b{ 3 };
    a2 = b;     // Use custom assignment
    std::cout << a2.an << std::endl;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

输出应该是:6,5,3

6A<int> a2是用 构造的值, 5是从 分配的值A<int> a13是从 分配的值B<int> b

注意:另一种方法是使用用户定义的转换函数,如 @LouisGo 评论的那样(见上文)。