int main()
{
int x = 1;
auto ref = std::ref(x);
if (x < ref)
{
...
}
}
In the above code, I made an int
variable and a reference_wrapper<int>
variable, and then compared them, and it works well.
However, If I change the type int
to string
, It raises a compile error like this.
binary '<': 'std::string' does not define this operator or a conversion to a type acceptable to the predefined operator
I thought that reference_wrapper<string>
would be implicitly converted to string
, but wouldn't.
Are there any rules that prevent implicit conversion from reference_wrapper<string>
to string
?
std::reference_wrapper<>
more or less supports only one operation: an implicit type conversion back to the original type (which is std::string
in your case).
But the problem is that the compiler has to know that an implicit conversion back to the original type is necessary.
That is why your example works with the built-in type int
, while not with the class template instantiation std::string
of the basic_string
class template.
The situation is similar to the below given example:
template<typename T>
struct MyWrapper
{
operator T()
{
return T{};
}
};
int main()
{
int x = 1;
MyWrapper<int> ref;
if(x < ref) //WORKS WITH INT
{
}
std::string x2 = "f";
MyWrapper<std::string> ref2;
if(x2 < ref2) //WON'T WORK WITH STD::STRING
{
}
}
To solve this problem, we need to explicitly say that we want the original type, which we can do by using the get()
member function, as shown below:
std::string x = "hi";
auto ref = std::ref(x);
//----------vvvvv------->get() member function used here
if (x < ref.get())
{
}