C ++多个副本分配运算符

问题描述

我正在学习C ++,我对赋值运算符有疑问。

根据此处https://en.cppreference.com/w/cpp/language/copy_assignment内容

...一个类可以具有多个副本分配运算符,例如都T& T :: operator =(const T&)和T&T :: operator =(T)。

我试图同时使用两个运算符创建一个类,但我看不出哪里出了问题,因为我是从编译器得到的:

错误C2593:“运算符=”不明确*

这是课程:

class Point2D
{
public:
    Point2D(); // default constructor
    Point2D(double xValue,double yValue); // overloaded constructor
    Point2D(const Point2D& ref); // copy constructor const
    Point2D(Point2D& ref); // copy constructor for copy and swap
    Point2D(Point2D&& moveRef); // move constructor

    ~Point2D(); // destructor

    Point2D& operator=( const Point2D& other ); // copy assignment operator const
    Point2D& operator=( Point2D other ); // copy assignment operator for copyAndSwap
private:
    double x;
    double y;

    int *ptr;
};

这是给我错误的地方:

void copy_assign_test()
{
    cout << endl << "copy assign" << endl;

    Point2D a(1,1);
    Point2D b(2,2);
    
    Point2D c(3,3);
    Point2D& ptRef = c;
    Point2D d(6,6);

    a = ptRef; // error: ambiguous operator
    b = a; // // error: ambiguous operator
    d = Point2D(7,7); // error: ambiguous operator
}

我的问题涉及以下方面:

  • 如果a=ptRef是引用,为什么ptRef含糊?
  • 如果未将b=a声明为引用,为什么a不明确?
  • 如果d = Point2D(7,7)不是参考,为什么Point2D(7,7)模棱两可?

我使用Visual Studio 2019和C ++ 17标准编译的所有测试。

解决方法

您引用的文档来自C ++标准的[class.copy](C ++ 14)/ [class.copy.assign] (C++17)部分:

15.8.2复制/移动分配运算符

  1. 用户声明的副本分配运算符X :: operator =是非静态的 具有 的X的非模板成员函数恰好是 类型X,X&,const X& ,volatile X&或const volatile X&。 121 [注意: 重载的赋值运算符必须声明为只有一个 参数;参见16.5.3.-尾注] [注:不止一种复制形式 可以为一个类声明赋值运算符。—尾注]

(添加了重点)

因此,您引用的文档是正确的,尽管它引用了标准中的 Note 。 [编辑:截图]

如果标准允许,为什么不编译?

在说明了允许哪些参数以及允许重载之后,该标准也不必说明哪些组合有效(无效),因为这将意味着重复自身。冗长的[over.match]第16.3节及其20页概述了超载解决方案规定(以及由此带来的歧义和冲突规则)。

,

a = ptRef;是很大的函数调用,因为ptRef可以由ref或value传递给const arg或不传递给const arg。 在您所有的情况下,分配都匹配两种模式。 无论如何,我不明白为什么在实施 Point2D& operator=( Point2D other );时需要使用Point2D& operator=( const Point2D& other );运算符。