为何std::reference_wrapper无法直接接收引用类型?编译报错解析
std::reference_wrapper使用引用类型作为模板参数为何编译失败?
我尝试用C++创建两个存储引用的vector:v1基于原始对象类型的std::reference_wrapper,v2基于引用类型的std::reference_wrapper,但v2编译失败。代码如下:
#include <string> #include <vector> int main (int argc, char* argv[]) { std::string object ("foobar"); std::string& refobj = object; std::vector<std::reference_wrapper<decltype(object)>> v1; // 以下代码编译失败 => 错误: forming pointer to reference type ‘std::__cxx11::basic_string<char>& std::vector<std::reference_wrapper<decltype(refobj)>> v2; std::vector<std::reference_wrapper<std::remove_reference_t<decltype(refobj)>>> v3; }
问题:
为什么v2编译报错?为什么必须先移除引用类型才能使用std::reference_wrapper?
原因解释
std::reference_wrapper的模板参数限制:
std::reference_wrapper<T>的模板参数T要求是对象类型(非引用、非函数的完整类型),它内部通过持有一个T*指针实现引用包装。如果T是引用类型(比如decltype(refobj)得到的std::string&),那么T*就变成了“指向引用的指针”——而C++语法明确禁止声明指向引用的指针,这就是编译器报错的直接原因。为什么要移除引用:
std::reference_wrapper的设计目标是包装对象的引用,而非“包装引用的引用”。当传入原始对象类型T时,它会自动提供T&的接口;但如果传入的是T&,就违反了它的模板参数约束,必须用std::remove_reference_t剥离引用属性,还原为原始对象类型,才能符合std::reference_wrapper的要求。
简单来说,std::reference_wrapper<T>里的T得是“被引用的对象类型”,不是“引用类型”本身。
内容的提问来源于stack exchange,提问作者abcdefg
相关产品推荐
相关产品推荐

