Opérateurs d'affectation de copie multiple c ++

Sep 10 2020

J'étudie le C ++ et j'ai une question concernant les opérateurs d'affectation.

Basé sur ce qui est écrit ici https://en.cppreference.com/w/cpp/language/copy_assignment, Il paraît que

... une classe peut avoir plusieurs opérateurs d'affectation de copie, par exemple T & T :: operator = (const T &) et T & T :: operator = (T).

J'ai essayé de créer une classe avec les deux opérateurs mais je ne vois pas où je me trompe, car j'obtiens ceci du compilateur:

erreur C2593: 'opérateur =' ambigu *

Voici la classe:

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

C'est là que ça me donne l'erreur:

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
}

Ma question concerne ce qui suit:

  • Pourquoi est a=ptRefambigu si ptRefc'est une référence?
  • Pourquoi est b=a-il ambigu si an'est pas déclaré comme référence?
  • Pourquoi est d = Point2D(7,7)ambigu si ce Point2D(7,7)n'est pas une référence?

Tous mes tests compilés à l'aide de Visual Studio 2019, avec le standard C ++ 17.

Réponses

4 bitmask Sep 10 2020 at 16:49

La documentation que vous citez dérive son énoncé de la section [class.copy](C ++ 14) / [class.copy.assign](C ++ 17) de la norme C ++ :

15.8.2 Opérateur d'affectation de copie / déplacement

  1. Un opérateur d'affectation de copie déclaré par l'utilisateur X :: operator = est une fonction membre non statique non-modèle de classe X avec exactement un paramètre de type X, X &, const X & , volatile X & ou const volatile X &. 121 [Remarque: Un opérateur d'assignation surchargé doit être déclaré comme n'ayant qu'un seul paramètre; voir 16.5.3.— note de fin] [Note: plusieurs formes d'opérateur d'affectation de copie peuvent être déclarées pour une classe.— note de fin]

(italiques ajoutés)

Ainsi, la documentation que vous citez est correcte, bien qu'elle fasse référence à une note dans la norme. [Edit: snip]

Pourquoi ne compile-t-il pas si la norme le permet?

Après avoir indiqué quels arguments sont autorisés et que les surcharges sont autorisées, le standard n'a pas à indiquer également quelles combinaisons sont (non) valides car cela signifierait se répéter. Les règlements sur la résolution des surcharges (et en vertu de celui-ci, les règles d'ambiguïté et de conflit) sont décrits dans la longue [over.match]section 16.3 avec ses 20 pages.