Hi everyone,
I was trying to implement by myself an analogous of the
std::pair
, which I called
ppair
. I wrote the following class (since everything is public), which is really simple.
I wrote
using vecint = typename std::vector<int,int>
in the main to be more coincise.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
|
#include <iostream>
#include <utility>
#include <vector>
template<typename T, typename U>
class ppair{
public:
T first;
U second;
ppair(): first{}, second{}{};
ppair(T& _first, U& _second): first{_first}, second{_second}{}
ppair(T&& _first, U&& _second): first{std::move(_first)}, second{std::move(_second)}{}
/*move semantic*/
//move cstr
ppair(ppair&& p): first{std::move(p.first)},second{std::move(p.second)}{
std::cout << "move cstr"<<"\n";
}
// move assign
ppair& operator=(ppair&& p){
std::cout <<"move assignment" <<"\n";
first=std::move(p.first);
second=std::move(p.second);
return *this;
}
};
int main(){
using vecint = typename std::vector<int>;
vecint v1{1,2,3};
vecint v2{4,5,6};
ppair<vecint, vecint> p1{v1,v2}; //custom cstr
ppair<vecint, vecint> p2{std::move(p1)}; //move cstr
std::cout << p1.first.size() << " " <<p1.second.size()<< "\t" <<p2.first.size() << " "<< p2.second.size()<<"\n";
ppair<vecint, vecint> p3{}; //def cstr
p3 = std::move(p2); //move assignment
std::cout <<p2.first.size()<< " "<<p2.second.size() << "\t" << p3.first.size()<<" " <<p3.first.size()<<"\n";
//WHY move assignment is not called here?
ppair<vecint, vecint> p4{ppair<vecint, vecint>(vecint{5}, vecint{5})};
return 0;
}
|
All the tests for the move semantics work, except for the last one, when I have that for
ppair<vecint, vecint> p4{ppair<vecint, vecint>(vecint{5}, vecint{5})};
only the default constructor is called, but I expected
ppair<vecint, vecint>(vecint{5}, vecint{5})
to be considered as an r-value, so that the move semantics is used. My professor told me that I can informally think an r-value as something that cannot be on the left hand side of an assignment. But this is not the case here, because the move constructor is not called.
Why is
only the custom constructor invoked, instead of the custom
and move constructor?
Actually, I've seen that if I write
ppair<vecint, vecint>(vecint{5}, vecint{5});
as a single statement, I don't have any compiler error. Why is that?