class Test {
public:
typedef std::set<std::pair<double, double>> DataSet;
explicit Test(const DataSet&& d) {
for (auto &itr : d) {
std::cout << "value1 = " << itr.first << '\n';
std::cout << "value2 = " << itr.second << '\n';
}
}
};
int main() {
//using namespace util;
try {
// Forwarding
Test obj( std::forward<Test::DataSet>(
{
{ 10.0, 20.0 },
{ 30.0, 40.0 },
{ 50.0, 60.0 }
}
));
std::cout << '\n';
// Move
Test obj2(std::move(Test::DataSet(
{
{ 10.0, 20.0 },
{ 30.0, 40.0 },
{ 50.0, 60.0 }
}
)
));
} catch (const std::exception& e) {
std::cerr << e.what() << std::endl;
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
Neither.
Test::DataSet(/*...*/)
is already a rvalue that can bind to a rvalue reference. The only thing std::move
does is to turn a lvalue into a xvalue (which is a rvalue), so that it can bind to a rvalue reference, which lvalues cannot. So std::move
is redundant.
std::forward
does the same only conditional on its template argument. So it is redundant (at best) as well.
const DataSet&&
as parameter makes no sense. You want either DataSet&&
which binds only to rvalues or const DataSet&
, which binds to rvalues and lvalues.
If you want to make use of the fact that the passed reference might be a rvalue (i.e. by moving from its members), then you need two overloads of your function. One taking DataSet&&
which is called with rvalue arguments and one taking const DataSet&
which is called with lvalue arguments.
In the specific case of the Test
function in your question, I don't see how there would be any benefit to moving from the members or do any other modification of the DataSet
state, so I would go with simply const DataSet&
as parameter and never bother with std::move
ing or std::forward
ing into that function specifically.