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)); // >--
}