When you return a std::vector from a function, is the compiler clever enough to use the vector’s Move Constructor and Move Assignment function to transfer ownership of the data to the receiving function?
#include <vector>
using ByteVector = std::vector<uint8_t>;
ByteVector getVector();
void setup() {
// Get vector of values
ByteVector values = getVector();
//
// Use values from the vector
//
// The vector's lifetime ends here. Dynamic storage space returned to the heap;
}
ByteVector getVector(){
ByteVector v;
// Put values in the vector
// Return the vector
return v;
}
void loop() {
}
Or must I use std::move() to avoid unnecessary copying?
#include <vector>
using ByteVector = std::vector<uint8_t>;
ByteVector getVector();
void setup() {
// Get vector of values
ByteVector values = getVector();
//
// Use values from the vector
//
// The vector's lifetime ends here. Dynamic storage space returned to the heap;
}
ByteVector getVector() {
ByteVector v;
// Put values in the vector
// Return the vector
return std::move(v);
}
void loop() {
}
Same question for a function returning a struct that contains a std::vector:
#include <vector>
using ByteVector = std::vector<uint8_t>;
struct MyStruct {
float floatValue;
ByteVector theVector;
};
MyStruct getStruct();
void setup() {
// Get vector of values
MyStruct values = getStruct();
//
// Use values from the struct
//
// The struct's lifetime ends here. Dynamic storage space returned to the heap;
}
MyStruct getStruct(){
MyStruct s;
// Put values in the struct;
// Return the struct
return s;
}
void loop() {
}
Even better: in many cases, you may not even get a move constructor call, and the returned value is constructed in-place (e.g. in the stack frame of the caller).
You should not move the returned value, that may actually result in worse performance. (If you return a struct or a tuple, you may want to move the members into the struct/tuple, though.)