13

How can we assign a value to an item wrapped by std::reference_wrapper?

int a[] = {0, 1, 2, 3, 4};

std::vector <std::reference_wrapper<int>> v(a, a+5);

v[0] = 1234;  // Error, can not assign value !

Accoring to error, direct assignment is deleted:

error: use of deleted function 'std::reference_wrapper<_Tp>::reference_wrapper(_Tp&&) [with _Tp = int]'

masoud
  • 55,379
  • 16
  • 141
  • 208

1 Answers1

17

Use the get() member function:

v[0].get() = 1111; // ok

Here is a list of all member functions of std::reference_wrapper. Since there is a operator=:

reference_wrapper& operator=( const reference_wrapper<T>& other );

the int literal is converted to a reference wrapper, which fails, and is the error message you see.

Alternatively, you could call the conversion operator explicit (static_cast<int&>(v[0]) = 1111;), but better use the get() method as showed above.

ipc
  • 8,045
  • 29
  • 33
  • 1
    Just wondering, what's the use of the conversion operator if it can't be used like this? I find `static_cast(v[0]) = 1111;` a bit dumb when `get()` is there. – chris Mar 17 '13 at 17:22
  • Maybe add that the non-explicit constructor of `std::reference_wrapper` is important here which e.g. `boost::reference_wrapper` has not. – Stephan Dollberg Mar 17 '13 at 17:26
  • 2
    @chris, it's so you can pass a `reference_wrapper` to a function taking `T&` (you could call `get()` there too, I guess, but it would just be more verbose). – Stephen Lin Mar 17 '13 at 17:50
  • @chris, the conversion operator is to get the reference out of the wrapper after passing it through some forwarding functions, it's not there to help you update the stored value. It wraps a reference, not a value. – Jonathan Wakely Mar 17 '13 at 19:49
  • @StephenLin, you _could_ call `get()` there, but the intended use case is for a function that expects a reference parameter so the conversion happens when initializing the function arguments, before entering the function, so the function doesn't usually see the `reference_wrapper` and doesn't even know it was there, and the caller is agnostic about what it's forwarding so doesn't want to have to add special-cases for `reference_wrapper`, it's usually a template argument that could be anything, so you want it to Just Work without extra effort – Jonathan Wakely Mar 17 '13 at 19:53
  • @JonathanWakely true, and that clearly makes sense...not sure why that was aimed at me though? :D I wasn't really suggesting `get()` when calling a function except to address the possibility because it was mentioned originally :) – Stephen Lin Mar 17 '13 at 20:05