1

Please consider following C++20 program:

#include <iostream>

struct A
{
    A() {}
    A( const A& ) = delete;
    A( A&& ) { std::cout << "m "; }
};

int main() {
    [[maybe_unused]] A a = {{A{}}};
}

I expected that move elision is required here according to the standard, so A( A&& ) will not be called. Still Clang calls it: https://gcc.godbolt.org/z/oobh7vWoh

Could you please clarify whether it is really permitted or not by the standard?

P.S. There is a similar question Copy elision for list-initialization, where is it stated in the standard? but it differs from this one by initializer_list constructor, so I do not think this one is a duplicate.

Fedor
  • 17,146
  • 13
  • 40
  • 131
  • I am not sure if this required as the rule for initialization is `In the initialization of an object, when the initializer expression is a prvalue of the same class type (ignoring cv-qualification) as the variable type` [Link](https://en.cppreference.com/w/cpp/language/copy_elision) – Simon Kraemer Jul 19 '21 at 07:05
  • @xskxzr, I am not sure because there is no initializer_list constructor in my case – Fedor Jul 19 '21 at 08:43
  • How is this distinct from your recent question that I [answered](https://stackoverflow.com/a/68433046/8586227)? – Davis Herring Jul 19 '21 at 08:43
  • That question has nothing to do with initializer_list. I answered that question with an example containing initializer_list. It is just an example. – xskxzr Jul 19 '21 at 09:26
  • But your example is opposite: https://gcc.godbolt.org/z/6G8d8oY3c from the example in this question. In this example clang calls two constructors, and in your example gcc does it. – Fedor Jul 19 '21 at 09:37
  • 1
    From https://cppinsights.io/ , `A a = {{A{}}}` is understood as `A a = A{{A{}}}`. (`A a = A{A{A{}}};` doesn't use move constructor BTW [Demo](https://gcc.godbolt.org/z/fno4cs1E7)). – Jarod42 Jul 19 '21 at 10:08

0 Answers0