Multiple return values (structured bindings) with unmovable types and guaranteed RVO in C++17

后端 未结 2 1205
刺人心
刺人心 2020-12-31 06:47

With C++ 17, we will have the possibility to return unmovable (including uncopyable) types such as std::mutex, via what can be thought of as guaranteed return v

2条回答
  •  庸人自扰
    2020-12-31 07:26

    Structured binding is defined to work on the basis of extracting references or pseudo-references to individual values. That is, if you do this:

    auto [x,y,z] = f();
    

    What you get is this something like this:

    auto HIDDEN_VALUE = f();
    auto &x = get<0>(HIDDEN_VALUE);
    auto &y = get<1>(HIDDEN_VALUE);
    auto &z = get<2>(HIDDEN_VALUE);
    

    When dealing with structs, x, y, and z won't be references; they will be something which "refers to" the actual array member, but it isn't an actual reference. The main point is that x, y and z are never copies of anything.

    As such, the question is whether HIDDEN_VALUE is copied. And it's clear that HIDDEN_VALUE is value constructed. And thus, if the return of f() is a prvalue, then the rules of guaranteed elision will apply.

    auto rvoStr = get_ensured_rvo_str().first;
    

    The expression get_ensured_rvo_str() is a prvalue. However, the result of applying .first to it is not a prvalue. Applying .first forces the prvalue (under guaranteed elision rules) to construct a temporary, with .first being applied to it. The element extracted, which is an xvalue, will be used to copy initialize rvoStr.

    So under no version of the standard is the copy into rvoStr elided.

    return many{SomeClass(),std::mutex(),std::string()};
    ...
    auto [ mtx,sc,str ] = get_class_and_mutex();
    

    I'm going to assume that you've made the necessary additions needed for the return statement to compile.

    Given that, the construction in the function will directly initialize the HIDDEN_VALUE at the return site. And each of the members of the aggregate will be initialized directly by prvalues, so no copying will happen.

提交回复
热议问题