为何std::reference_wrapper<int>未定义operator+=却能使用该运算符?
关于std::reference_wrapper的运算符使用疑问
我此前完全不了解用户定义转换函数及其工作原理,现在有个疑问:为何在std::reference_wrapper<int>未定义operator+=运算符的情况下,仍可使用该运算符?是否存在隐式转换?
测试代码与输出
测试1:模板函数调用
#include <iostream> #include <functional> #include <boost/type_index.hpp> using boost::typeindex::type_id_with_cvr; template <typename C> void test(C c) { c += 1; } int main() { int a = 3; test(a); std::cout << a << std::endl; test(std::ref(a)); std::cout << a << std::endl; }
输出:
3 4
测试2:直接传入std::reference_wrapper
void test_2(std::reference_wrapper<int> c) { c += 1; } int main() { int a = 3; test_2(std::ref(a)); std::cout << a << std::endl; }
输出:
4
测试3:加法运算的类型结果
int main() { int a = 3; auto b = std::ref(a); auto c = std::ref(a); auto d = b + c; std::cout << type_id_with_cvr<decltype(d)>().pretty_name() << std::endl; }
输出:
int
原因解析
核心在于std::reference_wrapper<T>提供了隐式转换为T&的用户定义转换函数——它重载了operator T&() const noexcept;。
- 当对
std::reference_wrapper<int>对象使用+=时,编译器会自动触发这个隐式转换,将其转为int&,随后调用int本身的operator+=,实际操作的是被引用的原始int变量,因此a的值会被修改。 - 对于
b + c的场景,两个std::reference_wrapper<int>都会被隐式转为int&,执行int的加法运算后,结果自然是int类型,所以d的类型为int。
这个转换函数是const成员函数,即使是const的std::reference_wrapper对象也能触发该转换。
内容的提问来源于stack exchange,提问作者Jonathan
相关产品推荐
相关产品推荐

