这是 std::ref 行为合乎逻辑吗?
Is this std::ref behaviour logical?
请考虑以下代码:
#include <iostream>
#include <functional>
int xx = 7;
template<class T>
void f1(T arg)
{
arg += xx;
}
template<class T>
void f2(T arg)
{
arg = xx;
}
int main()
{
int j;
j=100;
f1(std::ref(j));
std::cout << j << std::endl;
j=100;
f2(std::ref(j));
std::cout << j << std::endl;
}
执行时,此代码输出
107
100
我本来希望第二个值是 7 而不是 100。
我错过了什么?
对f2
的一个小修改提供了线索:
template<class T>
void f2(T arg)
{
arg.get() = xx;
}
现在,这将满足您的期望。
发生这种情况是因为std::ref
返回一个std::reference_wrapper<>
对象。重新绑定包装器的赋值运算符。(见 http://en.cppreference.com/w/cpp/utility/functional/reference_wrapper/operator%3D(
它不会对包装的引用进行赋值。
在f1
情况下,一切都按预期工作,因为std::reference_wrapper<T>
提供了一个转换运算符来T&
,该运算符将绑定到int
隐式operator+
的隐式右侧。
reference_wrapper
具有operator =
和非显式构造函数,请参阅文档。
所以,即使令人惊讶,这也是正常行为:
f2
将本地reference_wrapper重新绑定到xx
。
arg = xx;
本地arg
现在引用(读作绑定(xx
。(不再提及j
(
arg += xx;
应用隐式operator T& ()
来匹配operator +=
的参数,因此对引用的对象执行加法,即 j
.
因此,观察到的行为是正确的。
相关文章:
- 使用std::multimap迭代器创建std::list
- C++中std::resize(n)和std::shrink_to_fit之间的区别
- 来自 std::list 的迭代器 .end() 按预期返回"0xcdcdcdcdcdcdcdcd"但 .begin()
- C++17复制构造函数,在std::unordereded_map上进行深度复制
- 如何导出包含具有"std::unique_ptr"值的"std::map"属性的
- 从持续时间构造std::chrono::system_clock::time_point
- std::具有相同基类的类的变体
- 处理 std::enable_if<...中谓词的逻辑"OR">
- 想要将 CGAL 与四元数相结合是否合乎逻辑
- C++ 中计时的逻辑错误(使用 std::chrono)
- 对逻辑使用std::out_of_range是否错误
- 在我提供的此示例中,如何将2维std ::向量的逻辑更改为具有向量[row] [col] [col] [col] [co
- 函数返回样式合乎逻辑,没问题
- 是std :: any_of遵循短路逻辑所需的
- 如何实现 std::map::查找包含两个结构'Pos'结构的比较逻辑,每个结构包含 x 和 y 坐标
- std::查找多个元素和逻辑运算符
- 这是 std::ref 行为合乎逻辑吗?
- std::is_base_of 在 C++ 11 中的逻辑
- 是否可以覆盖std::string的==逻辑进行哈希处理
- 通过在移动赋值运算符中使用std::swap来重用析构函数逻辑有意义吗