std::ref() 和 & 都是引用
std::ref()
是C++标准库 <functional>
头文件中的函数模板,用于将一个对象包装成一个引用包装器(reference wrapper)。引用包装器允许你在使用函数模板时传递对象的引用而不是拷贝对象本身。
下面是 std::ref()
的基本用法和解释:
#include <iostream> #include <functional> int main() { int value = 42; // 使用 std::ref() 将对象包装成引用包装器 std::reference_wrapper<int> refValue = std::ref(value); // 修改原始对象的值 value = 99; // 通过引用包装器访问原始对象 std::cout << "Value through reference wrapper: " << refValue << std::endl; return 0; }
在这个例子中,std::ref(value)
创建了一个引用包装器 refValue
,它包装了整数 value
的引用。因此,refValue
就成为了 value
的引用,对 refValue
的修改会影响到原始的 value
。
在函数参数中直接使用引用 &
通常是更简单的方式,而且效果相同。std::ref()
主要用于在模板、泛型编程或需要将引用传递给函数对象的情况下。
使用 std::ref()
的主要原因之一是为了通过模板进行参数推断。当你在函数模板中使用引用时,编译器可能会尝试推断参数的引用性质,但在某些情况下推断可能不够明确。std::ref()
提供了一种明确的方式,让编译器知道你想要的是引用,而不是传递参数的拷贝。
考虑以下示例:
#include <iostream> #include <functional> // 使用引用参数的函数模板 template <typename T> void printValueRef(T& value) { std::cout << "Reference: " << value << std::endl; } // 使用引用包装器的函数模板 template <typename T> void printValueWrapper(std::reference_wrapper<T> value) { std::cout << "Reference Wrapper: " << value << std::endl; } int main() { int number = 123; // 使用引用传递 printValueRef(number); // 使用引用包装器 printValueWrapper(std::ref(number)); return 0; }
在这个例子中,printValueRef
和 printValueWrapper
都可以接受引用。
然而,当你使用模板时,有时候编译器可能无法准确地推断参数的引用性质,这时 std::ref()
可以提供更明确的语义。
总的来说,使用 std::ref()
是为了在模板或泛型场景中提供更明确的语义,并确保引用性质的正确推断。
在普通的函数中,直接使用引用通常更简洁和直观。