why

std::tie既能解包,也能赋值,怎么做到的?

template< class... Types >
tuple<Types&...> tie( Types&... args ) noexcept;

一个使用的例子,见参考链接2,直接贴代码

  • 比较自定义结构体, 非常干净,生成tuple,在c++17前,比std::make_tuple干净一些
#include <string>
#include <tuple>

struct person {
  std::string first_name;
  std::string last_name;
  int age;
};

inline auto tie_members(const person & x) noexcept {
  return std::tie(x.first_name, x.last_name, x.age);
}

inline bool operator<(const person & lhs, const person & rhs) noexcept {
  return tie_members(lhs) < tie_members(rhs);
}
  • 返回值解包,这也是cppref上的例子
bool was_inserted;
std::tie(std::ignore, was_inserted) = some_set.insert(some_value);

能看出来,传的是引用,然后改引用了。参考链接三有更详细的解释

简单说,std::tie实际上是引用形态的std::tuple<T>,或者std::tuple<T&>,通过std::tuple::operator=()来干活

template< class... UTypes >
tuple& operator=( const tuple<UTypes...>& other );

先声明变量,然后把引用拿过来,然后修改引用,这样变量就修改了。是比较猥琐的引用用法,这种用法实现上层组件还是很干净的,但还是需要声明一个变量来搞引用

c++17 结构化绑定彻底干掉了第二种解包需求。第一种还是可以继续用的。第一种在c++17上和make_tuple没区别(make_tuple可以通过类模板推导来省掉尖括号)

ref

  1. https://zh.cppreference.com/w/cpp/utility/tuple/tie
  2. http://bajamircea.github.io/coding/cpp/2017/03/10/std-tie.html
    1. 作者博客不错,这篇文章可以看一眼http://bajamircea.github.io/coding/cpp/2018/05/06/alex-stepanov-pearls.html
  3. https://stackoverflow.com/questions/43762651/how-does-stdtie-work

contact