The part I disagree with relates to "relying on the optimizer for placement". Even in C++ using the above factory pattern, you are returning the constructed object from a function - and there is no problem if it is ultimately part of some larger object. The C++ standard specifies copy-elision very precisely so you don't have to hope the optimizer does it - it is required to. To demonstrate you can do stuff like this even if you object contains non-moveable members, like std::mutex
class Foo
{
private:
std::mutex mutex_;
SomeComplexSubObject sub_;
Foo(SomeComplexSubObject sub) noexcept
: sub_{std::move(sub)}
{ }
public:
static std::optional<Foo> make(SomeParams params) noexcept
{
try {
return Foo{SomeComplexSubObject{params}};
}
catch (std::exception const& e) {
return std::nullopt;
}
}
};
I think Rust can also specify something like this (ie. "copy-elision") as part of its unwritten spec. Anyway, great article! :)