If you have a small (say, < 10 elements) std::vector<T>
of PODs, is there much benefit to using std::move()
?
In a codebase I'm looking at, I see a lot of code like this:
std::vector<double> temp{1.0, 2.0, 3.0, 6.0};
class some_class {
public:
some_class(const std::vector<double>& _vals) : vals{_vals} {}
private:
std::vector<double> vals;
}
some_class{temp};
// temp is never used again afterwards
I'm wondering if there's much benefit to changing it to this?
std::vector<double> temp{1.0, 2.0, 3.0, 6.0};
class some_class {
public:
some_class(std::vector<double>&& _vals) : vals{std::move(_vals)} {}
private:
std::vector<double> vals;
}
some_class{std::move(temp)};
// temp is never used again afterwards
CodePudding user response:
Using move semantics will likely avoid an extra allocation, which may or may not be considered significant in your domain. I doubt that copying of the elements itself is significant.
const std::vector<double>&
can't be replaced by std::vector<double>&&
because then the class becomes unusable with lvalue arguments.
It is possible to defined both overloads, but usually taking by-value and then moving into the member is sufficient. It may cost one extra move operation compared to two reference overloads, which is insignificant for std::vector
:
some_class(std::vector<double> _vals) : vals{std::move(_vals)} {}
Then the user of the class can move into the constructor if that makes sense in the program logic at the call site:
some_class{std::move(temp)};
(Although the above line creates and immediately destroys a temporary object, which probably doesn't make much sense to begin with.)
CodePudding user response:
You can change your variable declarations from
std::vector<double> temp{1.0, 2.0, 3.0, 6.0};
to any of these (whichever is better for you):
static const auto temp = {1.0, 2.0, 3.0, 6.0};
static const std::initializer_list<double> temp = {1.0, 2.0, 3.0, 6.0};
constexpr auto temp = {1.0, 2.0, 3.0, 6.0};
constexpr std::initializer_list<double> temp = {1.0, 2.0, 3.0, 6.0};
In this case when you will use this variable in expression
some_class{temp};
it will compile to basically same code as if you did
some_class{{1.0, 2.0, 3.0, 6.0}};