简体   繁体   English

如何正确使用std :: reference_wrappers

[英]How to correctly use std::reference_wrappers

I am trying to understand std::reference_wrapper . 我试图理解std::reference_wrapper

The following code shows that the reference wrapper does not behave exactly like a reference. 以下代码显示引用包装器的行为与引用不完全相同。

#include <iostream>
#include <vector>
#include <functional>

int main()
{
    std::vector<int> numbers = {1, 3, 0, -8, 5, 3, 1};

    auto referenceWrapper = std::ref(numbers);
    std::vector<int>& reference = numbers;

    std::cout << reference[3]              << std::endl;
    std::cout << referenceWrapper.get()[3] << std::endl; 
              // I need to use get ^
              // otherwise does not compile.
    return 0;
}

If I understand it correctly, the implicit conversion does not apply to calling member functions. 如果我正确理解,则隐式转换不适用于调用成员函数。 Is this an inherent limitation? 这是固有的限制吗? Do I need to use the std::reference_wrapper::get so often? 我需要经常使用std::reference_wrapper::get吗?

Another case is this: 另一种情况是:

#include <iostream>
#include <functional>

int main()
{
    int a = 3;
    int b = 4;
    auto refa = std::ref(a);
    auto refb = std::ref(b);
    if (refa < refb)
        std::cout << "success" << std::endl;

    return 0;
}

This works fine, but when I add this above the main definition: 这工作正常,但是当我在main定义上方添加以下代码时:

template <typename T>
bool operator < (T left, T right)
{
    return left.someMember();
}

The compiler tries to instantiate the template and forgets about implicit conversion and the built in operator. 编译器尝试实例化模板,而忽略了隐式转换和内置运算符。

Is this behavior inherent or am I misunderstanding something crucial about the std::reference_wrapper ? 这种行为是固有的还是我误解了有关std::reference_wrapper某些关键信息?

Class std::reference_wrapper<T> implements an implicit converting operator to T& : std::reference_wrapper<T>将隐式转换运算符实现为T&

operator T& () const noexcept;

and a more explicit getter: 还有一个更明确的getter:

T& get() const noexcept;

The implicit operator is called when a T (or T& ) is required. 当需要T (或T& )时调用隐式运算符。 For instance 例如

void f(some_type x);
// ...
std::reference_wrapper<some_type> x;
some_type y = x; // the implicit operator is called
f(x);            // the implicit operator is called and the result goes to f.

However, sometimes a T is not necessarily expected and, in this case, you must use get . 但是,有时不一定需要T ,在这种情况下,必须使用get This happens, mostly, in automatic type deduction contexts. 这种情况主要发生在自动类型推导上下文中。 For instance, 例如,

template <typename U>
g(U x);
// ...
std::reference_wrapper<some_type> x;
auto y = x; // the type of y is std::reference_wrapper<some_type>
g(x);       // U = std::reference_wrapper<some_type>

To get some_type instead of std::reference_wrapper<some_type> above you should do 要获取some_type而不是上面的std::reference_wrapper<some_type> ,您应该执行

auto y = x.get(); // the type of y is some_type
g(x.get());       // U = some_type

Alternativelly the last line above could be replaced by g<some_type>(x); 或者,可以将上面的最后一行替换为g<some_type>(x); . However, for templatized operators (eg ostream::operator <<() ) I believe you can't explicit the type. 但是,对于模板化的运算符(例如ostream::operator <<() ),我相信您不能显式该类型。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM