std :: tie和std :: make_tuple与std :: ref参数有什么区别?

时间:2016-04-25 11:46:46

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

编写表达式

之间是否存在语义差异
std::tie( x, y, z )

和以下表达式?

std::make_tuple( std::ref(x), std::ref(y), std::ref(z) )

如果是,那有什么区别?

顺便说一下,这个问题并不像What is the difference between assigning to std::tie and tuple of references?那样问,因为引用的元组不是通过std::ref创建的,而是通过显式指定类型。

2 个答案:

答案 0 :(得分:18)

两个表达式之间几乎没有功能差异。 tie()只是更短,make_tuple()更通用。

根据[tuple.creation],make_tuple确实:

template<class... Types>
constexpr tuple<VTypes...> make_tuple(Types&&... t);
     

对于类型中的每个Uidecay_t<Ti>Ti。如果Vi等于VTypes,则X&中的Ui reference_wrapper<X>Vi,否则Uistd::make_tuple( std::ref(x), std::ref(y), std::ref(z) )

因此std::tuple<X&, Y&, Z&>产生 a template<class... Types> constexpr tuple<Types&...> tie(Types&... t) noexcept;

另一方面,tie确实:

tuple<Types&...>(t...)
     

返回: t。当ignore中的参数为std::tie(x, y, z)时,将任何值分配给相应的元组元素都无效。

因此,std::tuple<X&, Y&, Z&>也会产生delete b[d];

除了一个edge case

答案 1 :(得分:16)

如果xyz中的任何一项是std::reference_wrapper的专业化,则会有所不同。

#include <tuple>
#include <functional>

void f(std::reference_wrapper<int> x, int y, int z)
{
    std::tie(x,y,z); // type is std::tuple<std::reference_wrapper<int>&, int&, int&>
    std::make_tuple(std::ref(x),std::ref(y),std::ref(z)); // type is std::tuple<int&, int&, int&>
}