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

前端 未结 2 527
醉酒成梦
醉酒成梦 2021-02-04 01:43

A class must have a valid copy or move constructor for any of this syntax to be legal:

C x = factory();
C y( factory() );
C z{ factory() };

In

2条回答
  •  不思量自难忘°
    2021-02-04 02:42

    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.

提交回复
热议问题