Sunday, March 9, 2014

ref-qualifiers

C++11 introduced the ability to "ref-qualifier" methods. The most known qualifier is the const one:

class T {
...
foo() const; // Here *this is const
...
}
view raw gistfile1.cpp hosted with ❤ by GitHub
however now is also possible to ref-qualify *this

class T {
...
foo() const; // *this is const
bar() &; // *this is an l-value
goo() &&; // *this is an r-value
...
};
view raw gistfile1.txt hosted with ❤ by GitHub
let see how this can be of any use. Immagine to have a factory building heavy objects and returning them by copy this way:

class JumboFactory {
...
Jumbo getJumboByCopy() {
return theJumboObject;
}
...
private:
Jumbo theJumboObject;
};
JumboFactory myJF;
Jumbo myJumbo = myJF.getJumboByCopy();
view raw gistfile1.txt hosted with ❤ by GitHub
in the following scenario we can avoid an useless copy:

Jumbo myJumbo = JumboFactory().getJumboByCopy();
view raw gistfile1.txt hosted with ❤ by GitHub
we can avoid the copy if Jumbo is movable overloading the method getJumboByCopy in case the object on which I'm calling it is a temporary:

class JumboFactory {
...
Jumbo getJumboByCopy() const & {
//Deep copy
return theJumboObject;
}
Jumbo getJumboByCopy() && { // *this is an r-value
//Move
return std::move(theJumboObject);
}
...
private:
Jumbo theJumboObject;
};
JumboFactory myJF;
Jumbo myJumboA = myJF.getJumboByCopy(); // Deep copy
Jumbo myJumboB = JumboFactory().getJumboByCopy(); // Move
view raw gistfile1.txt hosted with ❤ by GitHub
To be honest the example shows a scenario with other problems than the one mentioned (for instance if the object Jumbo is so big why permitting the copy then?) but I hope you got the idea.