приведение — c ++: оператор приведения против оператора присваивания против приоритета конструктора преобразования

Давайте иметь этот код:

Test1 t1;
Test2 t2;
t1 = t2;

Я считаю, что есть три (или более?) Способа, как реализовать t1 = t2

  • перегрузить оператор присваивания в Test1
  • перегрузить оператор приведения типа в Test2
  • создавать Test1(const Test2&) конструктор преобразования

Согласно моему тестированию GCC, это приоритет того, что используется:

  1. оператор присваивания
  2. конструктор преобразования и оператор приведения типа (неоднозначный)
  3. конструктор преобразования const и оператор приведения типа const (неоднозначный)

Пожалуйста, помогите мне понять, почему этот приоритет.

Я использую этот код для тестирования (раскомментируйте некоторые строки, чтобы попробовать)

struct Test2;
struct Test1 {
Test1() { }
Test1(const Test2& t) { puts("const constructor wins"); }
//  Test1(Test2& t) { puts("constructor wins"); }
//  Test1& operator=(Test2& t) { puts("assign wins"); }
};

struct Test2 {
Test2() { }
//  operator Test1() const { puts("const cast wins"); return Test1(); }
//  operator Test1() { puts("cast wins"); return Test1(); }
};int main() {
Test1 t1;
Test2 t2;
t1 = t2;
return 0;
}

6

Решение

Заявление t1 = t2; эквивалентно:

t1.operator=(t2);

Теперь применяются обычные правила разрешения перегрузки. Если есть прямое соответствие, это выбранный. Если нет, то неявные преобразования рассматриваются для использования с (автоматически сгенерированным, «неявно определенным») оператором копирования-назначения.

Существует два возможных неявных пользовательских преобразования. Все пользовательские преобразования считаются равными, и, если оба определены, перегрузка неоднозначна:

  • Перерабатывать t2 к Test1 через Test1::Test1(Test2 const &) конструктор преобразования.

  • Перерабатывать t2 к Test1 через Test2::operator Test1() const оператор приведения.

13

Другие решения

когда я использую следующий код, приоритет отдается сначала конструктору, а не оператору приведения

 #include<iostream>
using namespace std;
class C1;
class C2
{
int x;
public:
operator C2()
{
C2 temp;
cout<<"operator function called"<<endl;
return temp;
}
};
class C1
{
int x;
public:
C1():x(10){}
C1(C2)
{
cout<<"constructor called"<<endl;
}
};
int main()
{
C1 obj1;
C2 obj2;
obj1=obj2;
}

Конструктор вывода называется

0

По вопросам рекламы [email protected]