This has been bothering me for some time. Say we have a constructor that takes many parameters (copies or rvalues):
Object(A a, B b, C c, D d, ...);
When you need to use this constructor you can do it like this:
Object obj{{A params...}, {B params}, ...};
Which is great optimization-wise, since no copy and move constructors are called.
However, it can be hard to read at times. Also, perhaps A can be instantiated here but B and C will be passed as a copy. Therefore it makes sense to re-write it like this:
A a{A params...};
B b{B params...};
...
Object obj{a, b, ...}; // much nicer, but copy constructors are called
The problem is, with the latter approach, a copy constructor gets invoked for each parameter. This theoretically isn’t a problem, since we can use std::move
on temporary parameters:
A a{A params...};
B b{B params...};
...
Object obj{std::move(a), std::move(b), ...} // no copy!
But here, we get move constructors invoked.
Is there some way to enforce copy elision in such case – declare the variables but have the output like in the first case? It’s seems like a super simple optimization compiler could do but even -O3 doesn’t fix it.