Tonight I've been taking a look at some code I've been working on over the last few days, and began reading up on move semantics, specifically std::move. I have a few questions to ask you pros to ensure that I am going down the right path and not making any stupid assumptions!
Firstly:
1) Originally, my code had a function that returned a large vector:
template<class T> class MyObject
{
public:
std::vector<T> doSomething() const;
{
std::vector<T> theVector;
// produce/work with a vector right here
return(theVector);
}; // eo doSomething
}; // eo class MyObject
Given "theVector" is temporary in this and "throw-away", I modified the function to:
std::vector<T>&& doSomething() const;
{
std::vector<T> theVector;
// produce/work with a vector right here
return(static_cast<std::vector<T>&&>(theVector));
}; // eo doSomething
Is this correct? Any pitfalls in doing it this way?
2) I noticed in a function I have that returns std::string
that it automatically called the move constructor. Debugging in to Return of the String (thankyou, Aragorn), I noticed it called an explicit move constructor. Why is there one for the string class and not vector?
I didn't have to make any modifications to this function to take advantage of move semantics:
// below, no need for std::string&& return value?
std::string AnyConverter::toString(const boost::any& _val) const
{
string ret;
// convert here
return(ret); // No need for static_cast<std::string&&> ?
}; // eo toString
3) Finally, I wanted to do some performance tests, is the amazingly-fast results I got because of std::move semantics or did my compiler (VS2010) do some optimizing too?
(Implementation of _getMilliseconds()
omitted for brevity)
std::vector<int> v;
for(int a(0); a < 1000000; ++a)
v.push_back(a);
std::vector<int> x;
for(int a(0); a < 1000000; ++a)
x.push_back(a);
int s1 = _getMilliseconds();
std::vector<int> v2 = v;
int s2 = _getMilliseconds();
std::vector<int> v3 = std::move(x);
int s3 = _getMilliseconds();
int result1 = s2 - s1;
int result2 = s3 - s2;
The results were, obviously, awesome. result1, a standard assignment, took 630ms. The second result, was 0ms. Is this a good performance test of these things?
I know some of this is obvious to a lot of you, but I want to make sure I understand the semantics right before I go blazer on my code.
Thanks in advance!
See Question&Answers more detail:
os