In "classic" C ++ (C ++ 98), your initialization is copy-initialization
Unit a = 20;
really conceptually meant exactly
Unit a = Unit(20);
using the Unit::Unit(int) conversion constructor and then the Unit::Unit(const Unit &) copy constructor Unit::Unit(const Unit &) . However, even in the "classic" C ++ compiler it was allowed to exclude the formation of an intermediate temporary object and optimize the code before direct initialization (direct-initialization)
Unit a(20);
those. to exclude the call of the copy constructor even if the copy constructor had side effects. This optimization is called copy elision . (Even when copy elision was running, an accessible copy constructor was still required.)
Beginning with C ++ 17, a guaranteed copy elision appeared in the language, with which your initialization is treated as
Unit a(20);
without the requirement of having a copy constructor.
Those. in any case, you should not expect a mandatory call to the copy constructor here (and should never have been). In the "classic" C ++, the copy constructor could have been called here, but no more.
In your particular case, initialization by copying (copy-initialization) behaves identically to direct initialization (direct-initialization), but in general, significant differences between these forms of initialization are also preserved in C ++ 17. for example
struct A { A(int) {} }; struct B { operator int() const { return 0; } }; int main() { B b; A a1(b); // Все в порядке A a2 = b; // Ошибка }
PS There is no “assignment” here, of course, there is no trace.