Home > Software design >  How can std::reference_wrapper<int> use operator = if std::reference_wrapper doesn't have
How can std::reference_wrapper<int> use operator = if std::reference_wrapper doesn't have

Time:09-14

Thank you all, I didn't even know about user-defined conversion function and how it works.


Why is it possible to use std::reference_wrapper<int>::operator =, if such an operator does not exist, are there some implicit conversions?

#include <iostream>
#include <functional>
#include <boost/type_index.hpp>

using boost::typeindex::type_id_with_cvr;

template <typename C>
void test(C c)
{
    c  = 1;
}

int main()
{
    int a = 3;
    test(a);
    std::cout << a << std::endl;
    test(std::ref(a));
    std::cout << a << std::endl;
}

Output:

3
4

To check that template works perfectly fine:

void test_2(std::reference_wrapper<int> c)
{
    c  = 1;
}

int main()
{
    int a = 3;
    test_2(std::ref(a));
    std::cout << a << std::endl;
}

Output:

4

Still works as before. How is that possible?

Funny thing, that in auto d = b c, d has an integer type.

int main()
{
    auto b = std::ref(a);
    auto c = std::ref(a);
    auto d = b   c;
    std::cout << type_id_with_cvr<decltype(d)>).pretty_name() << std::endl;
}

Output:

int

CodePudding user response:

It's because it's implicitly convertible to a reference to T:

/* constexpr [c  20] */ operator T& () const noexcept;

In your case, it's implicitly convertible to an int&.


This ability to be implicitly convertible to an int& is also what would make it possible for you to define your function to take an int& while passing it a std::reference_wrapper<int>:

void test_2(int& c)       // <-- 
{                         //    |
    c  = 1;               //    |
}                         //    |
int main() {              //    |
    // ...                //    |
    test_2(std::ref(a));  // >-- 
}
  • Related