11

Can someone please explain why the following code prints 0 for f2? It seems like = {} somehow resolves to the int assignment operator.

#include <iostream>


struct Foo
{
    Foo() : x {-1} {}
    Foo(int x) : x{x} {}
    Foo& operator=(int y) { x = y; return *this; }
    Foo& operator=(const Foo& f) { x = f.x; return *this; }
    int x;
};

int main()
{
    Foo f1 = {};

    Foo f2;
    f2 = {};

    std::cout << f1.x << '\n';  // this prints -1
    std::cout << f2.x << '\n';  // this prints 0
}
Baum mit Augen
  • 49,044
  • 25
  • 144
  • 182
user2736667
  • 361
  • 1
  • 7
  • I had a similar issue where I had a member variable that was a string... and we changed something from a string to and int... and what I thought of as initialization but was really assignment so it invoked a crappy assignment operator `basic_string& operator=( CharT ch );` that accepted int and masked an error. – Grady Player Apr 30 '18 at 23:38
  • "`f2 = {}`" - the `{}` gets parsed as an expression, as an rvalue. Therefore, overload resolution prefers an rvalue over a `const` reference; then "{}" default-initializes the `int` parameter. That, at least, is my explanation. – Sam Varshavchik May 01 '18 at 00:26
  • @SamVarshavchik a braced list is never an expression. As mentioned by the duplicate, actually what happens is that `operator=(int)` and `operator=(const Foo &)` both enter the overload set; with the parameter being initialized by list initialization from an empty list. – M.M May 01 '18 at 02:24

0 Answers0