mardi 22 septembre 2015

Having a function only accept non-const lvalues

I have a function which sorts two vectors with the first of them as ordering criterion. Its signature is

template<typename A, typename B>
void sort(A&& X, B&& Y)
{
  ..
}

The problem is that universal references would allow nonsense cases like

sort(vector<int>{ 2,1,3 }, vector<int>{ 3,1,2 });

where an rvalue will be destroyed afterwards (nonsense).

Asking explicitly for a lvalue doesn't work since

template<typename A, typename B>
void sort(A& X, B& Y) ... // (*)

sort(vector<int>{2,1,3}, vector<int>{3,1,2});

for some reason the above compiles (I thought only const lvalues were allowed to bind to rvalues and to prolong their lifetime?).

If I add const to the lvalue reference then the function will no longer be able to modify the vectors and sort them.


My questions are:

1) Why in the example marked with // (*) can I bind a rvalue to a lvalue that is not even const ? Why instead something like int& r = 20; isn't allowed? What's the difference?

2) How can I solve my issue i.e. having the function accept only lvalues and not rvalue temporaries? (If it's possible, of course)

Obviously I'm allowed to use any C++ version available

Aucun commentaire:

Enregistrer un commentaire