为什么std :: make_tuple将std :: reference_wrapper <x>参数转换为X&amp;?</x>

时间:2013-09-27 15:18:45

标签: c++ c++11 tuples reference-wrapper

在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

我想知道:为什么参考包装器在这里处理特别?

3 个答案:

答案 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中复制它们会超出目的(如果删除复制构造函数,可能会破坏构建)。这就是为什么它在它的返回类型中使用引用(而不是值)的原因。