Copy/Move Constructor not invoked
-
Hi All,
Can some one help me understand, why either copy/move constructor is not called in this scenario.
class Hello { public: Hello() = default; Hello(const Hello&) { cout << "Copy ctor"; } Hello(Hello&&) { cout << "Move ctor"; } }; int main() { Hello a = Hello(); return 0; }
Does compiler does any optimization is this scenario ?
-
@Vinoth-Rajendran4
I'm going to stick my neck, because I'm not a C++ expert like some the people here.But if you were expecting it to create a default for
Hello a
and then assign (copy/move) to it from= Hello()
, I don't think it does that. I think C++ says this initialize-and-assign just create and initalizes with aHello()
. -
@Vinoth-Rajendran4
Yes. and I'm saying I believe C++ says create-and-assign is not treated as create followed by assign, it's just one operation. But I don't have a reference for you, so wait till someone other says so...! :)To allay your worries about optimization, I would do something with
a
just to make sure. -
@JonB said in Copy/Move Constructor not invoked:
But I don't have a reference for you, so wait till someone other says so...!
https://en.cppreference.com/w/cpp/language/direct_initialization
- If T is a class type,
- if the initializer is a prvalue expression whose type is the same class as T (ignoring cv-qualification), the initializer expression itself, rather than a temporary materialized from it, is used to initialize the destination object.
(Before C++17, the compiler may elide the construction from the prvalue temporary in this case, but the appropriate constructor must still be accessible: see copy elision)
- if the initializer is a prvalue expression whose type is the same class as T (ignoring cv-qualification), the initializer expression itself, rather than a temporary materialized from it, is used to initialize the destination object.
- If T is a class type,
-
@JonB said in Copy/Move Constructor not invoked:
And, IIRC some issue over this, which C++ version says T t = T(); does the same as T t(T()); ?
c++17
Have they always does behaved the same?
Yes for a very long time. Before codified into the standards the compilers just used to elide the copy (which they're free to do).
-
@kshegunov said in Copy/Move Constructor not invoked:
Before C++17, the compiler may elide the construction from the prvalue temporary in this case [...]
I'm still not understanding what this is saying. What is it that <= C++17 is allowed to do which >=C++20 is not?