views:

243

answers:

3
+6  A: 

No assignment operator is used in the first test-case. It just uses the initialization form called "copy initialization". Copy initialization does not consider explicit constructors when initializing the object.

struct A {
  A();

  // explicit copy constructor
  explicit A(A const&);

  // explicit constructor
  explicit A(int);

  // non-explicit "converting" constructor
  A(char const*c);
};

A a;
A b = a; // fail
A b1(a); // succeeds, "direct initialization"

A c = 1; // fail, no converting constructor found
A d(1); // succeeds

A e = "hello"; // succeeds, converting constructor used

Copy initialization is used in those cases that correspond to implicit conversions, where one does not explicitly kick off a conversion, as in function argument passing, and returning from a function.

Johannes Schaub - litb
+2  A: 

Your first set is according to the C++ standard, and not due to some optimization.

Section 12.8 ([class.copy]) of the C++ standard gives a similar example:

class X {
    // ...
public:
    X(int);
    X(const X&, int = 1);
};

X a(1);     // calls X(int);
X b(a, 0);  // calls X(const X&, int);
X c = b;    // calls X(const X&, int);

The last line would be the one matching your case.

stakx
+2  A: 

C++ standard 8.5/12

The initialization that occurs in argument passing, function return, throwing an exception (15.1), handling an exception (15.3), and brace-enclosed initializer lists (8.5.1) is called copy-initialization and is equivalent to the form

T x = a;

The initialization that occurs in new expressions (5.3.4), static_cast expressions (5.2.9), functional notation type conversions (5.2.3), and base and member initializers (12.6.2) is called direct-initialization and is equivalent to the form

T x(a);
Andreas Brinck