mardi 29 mars 2016

Is assignment to r-value allowed if move constructor present even when assignment operators are deleted?

Consider the following code, which compiles under Clang, GCC, and VS 2015 (online example):

#include <utility>

class S 
{
public:
    S(int x) : i(x) { }
    ~S() { }

    S(S&&)  = default;

    S(const S& )            = delete;
    S& operator=(S&&)       = delete;
    S& operator=(const S&)  = delete;

private:
    int i;
};

S GetS() 
{ 
    // This is a contrived example with details elided. Assume 
    // there's a reason in the actual use case for returning via 
    // std::move.
    return std::move( S(999) ); 
}

int main()
{
    S tmp = GetS(); // <-- Assignment allowed even though assignment operator is deleted?

    return 1;
}

I'm unclear as to why the line

S tmp = GetS(); 

compiles, executing the move constructor instead of the move assignment operator.

I know that RVO allows construction and assignment to be elided as an optimization, but it was my understanding that explicitly deleting an operator should cause compilation to fail if that operator is explicitly used in the code.

Is there some clause in the C++11 specification that allows a compiler to transform assignment initialization into copy construction, even when assignment operators for a type have been explicitly deleted?

Aucun commentaire:

Enregistrer un commentaire