Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

c++ multiple copy assignment operators

I'm studying C++ and I have a question regarding assignment operators.

Based on what is written here https://en.cppreference.com/w/cpp/language/copy_assignment, it seems that

...a class can have multiple copy assignment operators, e.g. both T& T::operator=(const T &) and T& T::operator=(T).

I tried to make a class with both operators but I don't see where I'm wrong, because I get the this from the compiler:

error C2593: 'operator =' ambiguous*

This is the class:

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;
};

This is where it gives me the error:

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
}

My question concerns the following:

  • Why is a=ptRef ambiguous if ptRef is a reference?
  • Why is b=a is ambiguous if a isn't declared as reference?
  • Why is d = Point2D(7,7) ambiguous if Point2D(7,7) isn't a reference?

All my tests compiled using Visual Studio 2019, with the C++17 standard.

like image 709
Gianluca Avatar asked Oct 16 '22 00:10

Gianluca


1 Answers

The documentation you cite derives its statement from the C++ standard's [class.copy] (C++14) / [class.copy.assign] (C++17) section:

15.8.2 Copy/move assignment operator

  1. A user-declared copy assignment operator X::operator= is a non-static non-template member function of class X with exactly one parameter of type X,X&,const X&,volatile X& or const volatile X&.121[Note: An overloaded assignment operator must be declared to have only one parameter; see 16.5.3.— end note] [Note:More than one form of copy assignment operator may be declared for a class.— end note]

(emphasis added)

So, the documentation you cite is correct, although it refers to a Note in the standard. [Edit: snip]

Why doesn't it compile if the standard allows it?

After stating which arguments are allowed and that overloads are allowed, the standard doesn't have to also state which combinations are (in-)valid because that would mean repeating itself. Overload resolution regulations (and by virtue of it, ambiguity and conflict rules) are outlined in the lengthy [over.match] section 16.3 with its 20 pages.

like image 167
bitmask Avatar answered Nov 15 '22 10:11

bitmask