C++ 如何正确使用 std::reference_wrappers
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18127469/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to correctly use std::reference_wrappers
提问by Martin Drozdik
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
?
回答by Cassio Neri
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:
和更明确的吸气剂:
T& get() const noexcept;
The implicit operator is called when a T
(or T&
) is required. For instance
当需要 a T
(or T&
)时会调用隐式运算符。例如
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
. This happens, mostly, in automatic type deduction contexts. For instance,
但是,有时 aT
不一定是预期的,在这种情况下,您必须使用get
. 这主要发生在自动类型推导上下文中。例如,
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);
.
However, for templatized operators (e.g. ostream::operator <<()
) I believe you can't explicit the type.
或者,上面的最后一行可以替换为g<some_type>(x);
. 但是,对于模板化的运算符(例如ostream::operator <<()
),我相信您无法明确类型。