lundi 5 janvier 2015

Perfect forwarding and the scope of temporary objects

In an attempt to realize perfect forwarding for the * operator I constructed the following example.



#include <string>
#include <iostream>

class A {
public:
std::string name;
A(const A& _other) : name(_other.name) {
std::cout << "Copy-Construct with name: " << name << std::endl;
}
A(A&& _other) : name(std::move(_other.name)) {
std::cout << "Move-Construct with name: " << name << std::endl;
}
A(std::string _name): name(_name) { }
};

A operator*(const A& _lhs, const A& _rhs) {
std::cout << "Start Operator Copy with: " << _lhs.name << " " << _rhs.name << std::endl;
A bla(_lhs.name+" "+_rhs.name);
return bla;
}

A&& operator*(A&& _lhs, const A& _rhs) {
std::cout << "Start Operator Move with: " << _lhs.name << " " << _rhs.name << std::endl;
_lhs.name += " "+_rhs.name;
return std::move(_lhs);
}

int main() {
A a("a");
A b("b");
A c("c");
A d("d");

A x = a*b*A("t1")*c*A("t2")*A("t3")*d;

std::cout << "Final result is: " << x.name << std::endl;
}


The result is as I hoped, in particular only one move constructor and no copy constructor is called.



Start Operator Copy with: a b
Start Operator Move with: a b t1
Start Operator Move with: a b t1 c
Start Operator Move with: a b t1 c t2
Start Operator Move with: a b t1 c t2 t3
Start Operator Move with: a b t1 c t2 t3 d
Move-Construct with name: a b t1 c t2 t3 d
Final result is: a b t1 c t2 t3 d


Now my question is: Is this leagal C++11 code? In particular can I rely on the fact that the first temporary object (contructed from a and b) leaves its scope at the semicolon and not before that? And is the construction, to return an object obtained as a move reference back as a move reference, legal at all?


Aucun commentaire:

Enregistrer un commentaire