【问题标题】:What is the difference between std::tie and std::make_tuple with std::ref arguments?带有 std::ref 参数的 std::tie 和 std::make_tuple 有什么区别?
【发布时间】:2025-12-23 01:40:07
【问题描述】:
【问题讨论】:
标签:
c++
c++11
reference
tuples
【解决方案1】:
这两个表达式之间几乎†没有功能上的区别。 tie() 更短,而make_tuple() 更通用。
根据 [tuple.creation],make_tuple 会:
template<class... Types>
constexpr tuple<VTypes...> make_tuple(Types&&... t);
对于类型中的每个Ti,让Ui 为decay_t<Ti>。那么如果Ui 等于reference_wrapper<X>,则VTypes 中的每个Vi 是X&,否则Vi 是Ui。
因此std::make_tuple( std::ref(x), std::ref(y), std::ref(z) ) 产生†std::tuple<X&, Y&, Z&>。
另一方面,tie 会:
template<class... Types>
constexpr tuple<Types&...> tie(Types&... t) noexcept;
返回: tuple<Types&...>(t...)。当t 中的参数为ignore 时,将任何值赋给对应的元组元素均无效。
因此,std::tie(x, y, z) 也会产生 std::tuple<X&, Y&, Z&>。
†edge case 中的一个除外。
【解决方案2】:
x、y 和 z 中的任何一个是 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&>
}