3
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?

0

3 Answers 3

2

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())
{
        
}
Sign up to request clarification or add additional context in comments.

Comments

2

My guess is because std::string is a template instantiation of std::basic_string and therefor when it tries to call the operator it can't find an exact match. link to std::string operator definitions

1 Comment

Welcome to Stack Overflow and thanks for the nice first/second contribution!
1

Use std::reference_wrapper<T>::get for explicit conversion.

int is a primitive data type, while string is a template type as mentioned by Tyler Wojciechowski.


Illustration

int main()
{
    string x = "hi";
    auto ref = std::ref(x).get();
    if (x < ref)
    {
        ...
    }
}

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.