在C ++ 11标准中,它指出(参见cppreference.com,另见标准的第20.4.2.4节),它指出
template< class... Types >
tuple<VTypes...> make_tuple( Types&&... args );
创建一个元组对象,从参数类型中推导出目标类型。
对于
Ti
中的每个Types...
,Vi
中的相应类型Vtypes...
为std::decay<Ti>::type
,除非std::decay
的应用导致{{1}对于某些类型std::reference_wrapper<X>
,在这种情况下,推导的类型为X
。
我想知道:为什么参考包装器在这里处理特别?
答案 0 :(得分:11)
这或多或少是reference_wrapper
的主要目的。
通常,std::make_tuple
总是生成值的元组(std::decay
模拟按值传递语义)。鉴于int x, y; std::make_tuple(x, y);
生成std::tuple<int, int>
,即使它已将Types
推导为一组参考int&, int&
。 std::decay
会将这些内容转换为int, int
。
reference_wrapper
允许您强制创建引用的元组:std::make_tuple(std::ref(x), y)
将生成std::tuple<int&, int>
。
标准库的其他部分以相同的方式使用reference_wrapper
。例如,std::bind
通常会将绑定参数复制/移动到结果对象中,但如果您希望它只存储引用,则可以通过传递reference_wrapper
显式请求它。
答案 1 :(得分:4)
您的标题具有误导性:使用std::reference_wrapper<X>
将成员变为X&
而不是X
。完成此转换的原因是std::reference_wrapper<T>
是辅助类型,用于将值类型转换为引用类型。但是,使其显示的额外转换有时会干扰使用。因此,在可能的情况下展开引用似乎是一种合理的方法:使std::tuple<...>
成员T&
使得使用更加自然。
答案 2 :(得分:0)
人们通常使用std::reference_wrapper<X>
来保存不可复制的类型。因此,在make_tuple
中复制它们会超出目的(如果删除复制构造函数,可能会破坏构建)。这就是为什么它在它的返回类型中使用引用(而不是值)的原因。