Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

c++: cast operator vs. assign operator vs. conversion constructor priority

Let's have this code:

Test1 t1;
Test2 t2;
t1 = t2;

I believe there are three (or more?) ways how to implement t1 = t2

  • to overload assign operator in Test1
  • to overload type cast operator in Test2
  • to create Test1(const Test2&) conversion constructor

According to my GCC testing, this is the priority of what is used:

  1. assign operator
  2. conversion constructor and type cast operator (ambiguous)
  3. const conversion constructor and const type cast operator (ambiguous)

Please help me understand why this priority.

I use this code for testing (uncomment some lines to try out)

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;
}
like image 509
Jan Turoň Avatar asked Sep 09 '12 00:09

Jan Turoň


1 Answers

The statement t1 = t2; is equivalent to:

t1.operator=(t2);

Now the usual rules of overload resolution apply. If there's a direct match, that's the chosen one. If not, then implicit conversions are considered for use with the (automatically generated, "implicitly defined") copy-assignment operator.

There are two possible implicit, user-defined conversions. All user-defined conversions count equal, and if both are defined, the overload is ambiguous:

  • Convert t2 to a Test1 via the Test1::Test1(Test2 const &) conversion constructor.

  • Convert t2 to a Test1 via the Test2::operator Test1() const cast operator.

like image 95
Kerrek SB Avatar answered Oct 24 '22 09:10

Kerrek SB