reference_wrapper of a left reference

61 Views Asked by At

In the following code, I try to use a vector v1 made of references of a type and a vector v2 made of a reference of a type:

#include <string>
#include <vector>

int main (int argc, char* argv[])
{
   std::string  object ("foobar");
   std::string& refobj = object;

   std::vector<std::reference_wrapper<decltype(object)>> v1;

   // The following line doesn't compile => error: forming pointer to reference type ‘std::__cxx11::basic_string<char>&
   std::vector<std::reference_wrapper<decltype(refobj)>> v2;
   
   std::vector<std::reference_wrapper<std::remove_reference_t<decltype(refobj)>>> v3;
}

As expected, the code compile for v1 but not for v2, which should be ok as well IMHO; in such a case, the reference wrapper should do nothing since the provided type is already a reference.

Note that I can achieve what I want with vector v3 but the code seems a little bit cumbersome.

Question: why the compiler is not happy while compiling v2? In other words, why should I first remove the type reference before adding one with reference_wrapper ?

1

There are 1 best solutions below

0
463035818_is_not_an_ai On BEST ANSWER

In other words, why should I first remove the type reference before adding one with reference_wrapper ?

reference_wrapper does not actually "add a reference". It just emulates reference semantics, but at the same time allows to rebind the "reference". Rebinding isnt possible with references. Thats one reason why std::reference_wrapper exists in the first place.

Could std::reference_wrapper strip off the reference for you? Yes it could do the same as you did manually. However, trying to handle all types that don't match with std::reference_wrapper is beyond the scope of std::reference_wrapper. Getting a compiler error is "good enough". Moreover, it would be rather confusing when std::reference_wrapper<T>::type could be different from T.

You can use std::ref :

#include <string>
#include <vector>

int main (int argc, char* argv[])
{
   std::string  object ("foobar");
   std::string& refobj = object;
   std::vector<decltype(std::ref(refobj))> v3;
}