dimanche 1 avril 2018

Why Structured Binding disables both RVO and implicit move?

Suppose we have a class named Bar, that supports both move/copy, as follows:

class AAA
{
public:
    AAA() = default;
    ~AAA() = default;
    AAA(const AAA&) = default;
    AAA(AAA&&) = default;
};

It's frustrating to know that returning one of AAA elements from Structured Bindings does NOT only take advantage of RVO but also prevent compilers from applying an implicit std::move as follows:

AAA get_val()
{
    // Get std::tuple<AAA, AAA, AAA>
    auto [ first, second, third ]  = get_tpl();

    // No RVO
    // No implicit move
    return second;
}

I've tested both clang and gcc, both of which made a copy of second.

I guess the reason RVO is not performed is that, probably the compiler sees them as not a real local variable, but a reference to the object, by which it fails to meet the condition to perform it - the types aren't the same.

But why isn't move performed either? Isn't the move-is-guaranteed-when-RVO-disappears rule our globally accepted belief?

I can't find the exact quote describing this in the standard, and can't quite understand the reasoning behind this.

Aucun commentaire:

Enregistrer un commentaire