0
template<typename T>
class Numeric
{
public:
    Numeric() : val(T()) { cout << "ctor default\n"; }
    explicit Numeric(const T& v) : val(v) { cout << "ctor value\n"; }
    Numeric(const Numeric& v) : val(v.val) { cout << "copy ctor\n"; }
    Numeric(Numeric&& v) { val = v.val; cout << "cmove\n"; v.val = 0; }
    Numeric& operator=(const Numeric& v) { val = v.val; cout << "copy assignment\n"; return *this; }
    Numeric& operator=(Numeric&& v) { val = v.val;cout << "amove\n"; return *this; }
    ~Numeric() { cout << "dtor\n"; };

private:
    T val;

};

// ----------- main ------
Numeric<int> c1(Numeric<int>(2)); // calls the normal constructor instead of copy constructor

I would expect that the copy constructor gets called, but thats not the case, instead the constructor for value initialization gets called.

What is going on here? It seems there is an inplicit conversion going on, but i dont understand why.

if i explicitly convert it, like this

Numeric<int> c1(Numeric<int>(Numeric<int>(2)));

the move constructor and than the destructor are getting called.

  • Try compiling with `-fno-elide-constructors`? – Kerrek SB Aug 18 '18 at 18:10
  • See [copy.class] for where copy elision can take place (or can't), Notable in your case is § 12.8.31.3 *"when a temporary class object that has not been bound to a reference (12.2) would be copied/moved to a class object with the same cv-unqualified type, the copy/move operation can be omitted by constructing the temporary object directly into the target of the omitted copy/move."* Also see [this question](https://stackoverflow.com/questions/12953127/what-are-copy-elision-and-return-value-optimization) – WhozCraig Aug 18 '18 at 18:19

1 Answers1

2

Aha, you have stumbled onto copy elision. See https://en.cppreference.com/w/cpp/language/copy_elision for more details. The first example on that page is the exact situation you describe.

You can invoke the copy ctors by just changing your main to

Numeric<int> c0(2);
Numeric<int> c1(c0);
cplusplusrat
  • 1,435
  • 12
  • 27