Hi,
Guaranteed copy elision in C++17 is pretty great. This way I can simply return by value in my factory functions. Basically these factory functions act like external constructors (but not perfectly).#include <memory>
extern widget factory();
int main() {
auto w1 = widget{ factory() };
auto w2 = new widget{ factory() };
auto w3 = std::unique_ptr<widget>{new widget{ factory() }};
return 0;
}
Basically all three cases have guaranteed copy elision. It would be nice if we could put elements from these kind of factory functions into a container and eliding copying at the same time. Now the only interface for something like this is the emplace* family of functions, but they only work with constructors. I suggest a function with the following signature.//for vector
template <class Func, class... Args>
reference emplace_back_from_function(Func func, Args... args);
The container then calls placement new inside somewhere:Maybe allocators need an updated interface for it too as placement new through the indirection of allocator_traits::construct brakes guaranteed copy elision (I think).new(pos) value_type{ func(std::forward<Args>(args)...) };
This way we could make collections of non-copyable and even non-movable types as guaranteed copy elision is allowed for these too.
std::make_shared could have a std::make_shared_from_function counterpart too. Maybe there are other parts of the standard library that calls constructors of user specified types that could make advantage of this.
Thoughts?
Lénárd Szolnoki--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-pr...@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/0144b887-c694-4f3e-b368-32645a1562d9%40isocpp.org.
This almost works... the trouble is that perfect forwarding gets in the way (unsurprisingly, since "perfect" forwarding is imperfect for prvalues). allocator::construct will donew (loc) T(forward<Arg>(arg)...)where we need the argument to the constructor to be a *prvalue* of type T. Possibly we could modify the construction logic to use a mechanism that acts like forward<T> for most Ts, but invokes the wrapped function when T is emplace_using<Fn>.