initializing a non-copyable member (or other object) in-place from a factory function

▼魔方 西西 提交于 2019-12-03 00:00:00

On your main question:

The question is, how to initialize a nonstatic member from a factory function returning non-copyable, non-moveable type?

You don't.

Your problem is that you are trying to conflate two things: how the return value is generated and how the return value is used at the call site. These two things don't connect to each other. Remember: the definition of a function cannot affect how it is used (in terms of language), since that definition is not necessarily available to the compiler. Therefore, C++ does not allow the way the return value was generated to affect anything (outside of elision, which is an optimization, not a language requirement).

To put it another way, this:

C c = {...};

Is different from this:

C c = [&]() -> C {return {...};}()

You have a function which returns a type by value. It is returning a prvalue expression of type C. If you want to store this value, thus giving it a name, you have exactly two options:

  1. Store it as a const& or &&. This will extend the lifetime of the temporary to the lifetime of the control block. You can't do that with member variables; it can only be done with automatic variables in functions.

  2. Copy/move it into a value. You can do this with a member variable, but it obviously requires the type to be copyable or moveable.

These are the only options C++ makes available to you if you want to store a prvalue expression. So you can either make the type moveable or return a freshly allocated pointer to memory and store that instead of a value.

This limitation is a big part of the reason why moving was created in the first place: to be able to pass things by value and avoid expensive copies. The language couldn't be changed to force elision of return values. So instead, they reduced the cost in many cases.

Issues like this were among the prime motivations for the change in C++17 to allow these initializations (and exclude the copies from the language, not merely as an optimization).

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!