I have a function that produces-returns a value of a class type Value.
Value compute();
Now, I want to create a new object of type Value in an existing storage, and initialize it with the value returned by compute. When I use placement new for this initialization, and deferred temporary materialization/NRVO is applied, then, the new object is initialized “directly”.
new (storage) Value(compute()); // single constructor of Value called
However, when I use std::construct_at, then, an additional call of Value's copy/move constuctor is called:
std::construct_at<Value>(storage, compute()); // additional copy/move constructor called
This is not only less efficient in general, but also unusable for non-movable types. My question is whether there is a way to use std::construct_at in this scenario without the additional copy/move constructor call. (I don't think so, but want to be sure.)
More elaborated online demo: https://godbolt.org/z/sc98Px3hW
std::construct_at<T>(storage)always value initializes an object ~new (storage) T{}.std::construct_at()blocks NRVO? That might lead to a more precise title ("Can I use NRVO with std::construct_at() ?" or similar).uninitialized_move? godbolt.org/z/W9caod7E6Value v = compute();and let the compiler + optimizer sort it out. Only if this was happening in a provable hot path and had an actual/provable impact would I care to look at it. But I think such a situation would be rare, so mostly I'd just leave it alone.