3

Using push_back with rvalue references?

I have the following code:

csvData.push_back(CsvDataSet(csvBlock));

Should I instead do this:

csvData.push_back(std::move(CsvDataSet(csvBlock)));

That way I save one copy operation.

1
  • 1
    You should make it clear wether CsvDataSet is a class or a function returning some value.
    – Felix Glas
    Commented Jan 17, 2014 at 15:50

2 Answers 2

10

Assuming CsvDataSet to be a class: No, you shouldn't. CsvDataSet(csvBlock) is already an rvalue. More precisely, it is an prvalue.

Therefore in both cases, void std::vector::push_back( T&& value ); will be called.

6
  • OK I should remove the templates from my code. It was a question about classes in general, not templates. Commented Jan 17, 2014 at 15:24
  • Aha I get it, so that is already a temporary value, that is an rvalue. Nice! Commented Jan 17, 2014 at 15:26
  • The result of calling a converting constructor is a prvalue.
    – MWid
    Commented Jan 17, 2014 at 16:00
  • 1
    Why should it make a difference, if the constructor is declared explicit or not?
    – MWid
    Commented Jan 17, 2014 at 16:14
  • @MWid, yeah, you are right. Had a little bit of confusion going on there reading the standard. Could you please check if the current version is ok? Thanks.
    – Shoe
    Commented Jan 19, 2014 at 10:25
6

I think in your case you should use emplace_back().

"Appends a new element to the end of the container. The element is constructed in-place, i.e. no copy or move operations are performed. The constructor of the element is called with exactly the same arguments that are supplied to the function."

Not sure, but I think it is equivalent for using push_back(std::move(T())), but maybe the downvoter correct me, please. Clarification the result should be the same, but emplace forwards arguments to constructor and constructs elements in place, while push_back calls move constructor, or normal one and then moves object.

Edit: if the downvoter agrees with the reasoning presented by @user3111311 below I urge to read Example section in emplace_back().

8
  • 1
    emplace_back is redundant in c++11, push_back should be used instead Commented Jan 17, 2014 at 15:23
  • 1
    @user3111311 What?! Can you back it up? It was introduced in c++11. Why would the standard committee include something redundant? Is that an aesthetic opinion?
    – luk32
    Commented Jan 17, 2014 at 15:26
  • 1
    emplace_back was meant to be an "efficient" version of push_back. Now that we have push_back for rvalue references, it is not needed. It is kept in c++11 for backwards compatibility. Commented Jan 17, 2014 at 15:29
  • 6
    @user3111311 emplace_back is not redundant in C++11. There are specific forms of emplace_back that was provided by different compilers that are non comformant and redundant (see this). However the correct form of emplace_back taking the constructor parameters directly e.g. csvData.emplace_back(csvBlock) is not redundant. It will construct the object in place instead of performing a move construct as void push_back(T&&)
    – Felix Glas
    Commented Jan 17, 2014 at 15:33
  • 2
    @luk32 Yes, emplace can do that. Passing a T const& or T&& to emplace_back has identical effect to passing a T const& or T&& to push_back.
    – Casey
    Commented Jan 17, 2014 at 17:40

Not the answer you're looking for? Browse other questions tagged or ask your own question.