为什么 reference_wrapper<string> 比较不起作用?

Why does reference_wrapper<string> comparison not work?

int main()
{
    int x = 1;
    auto ref = std::ref(x);
    if (x < ref)
    {
        ...
    }
}

在上面的代码中,我做了一个int变量和一个reference_wrapper<int>变量,然后比较它们,效果很好。

但是,如果我将类型 int 更改为 string,它会引发这样的编译错误。

binary '<': 'std::string' does not define this operator or a conversion to a type acceptable to the predefined operator

我认为 reference_wrapper<string> 会隐式转换为 string,但不会。
是否有任何规则可以防止从 reference_wrapper<string>string 的隐式转换?

我的猜测是因为 std::string 是 std::basic_string 的模板实例化,因此当它试图调用运算符时它找不到完全匹配。 link to std::string operator definitions

使用std::reference_wrapper<T>::get 用于显式转换。

intprimitive 数据类型,而 stringtemplate 类型 Tyler Wojciechowski.


插图

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

std::reference_wrapper<> 或多或少只支持一种操作:隐式类型转换 返回原始类型(在您的情况下是 std::string)。

但是 问题 是编译器必须知道 隐式转换 回到原始类型是 必要.

这就是为什么您的示例适用于 built-in 类型 int,而不适用于 class 模板实例 std::string basic_string class 模板。

情况类似于下面给出的示例:

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
    {
        
    }
    
}

解决这个问题,我们需要明确的说我们想要原始类型,我们可以使用get()成员函数来实现,如下所示:

std::string x = "hi";
auto ref = std::ref(x);
//----------vvvvv------->get() member function used here
if (x < ref.get())
{
        
}