在c++ 11标准库中,加入了std::tie,在c++ 14中改进,方便使用。 其与tuple关系密切, 主要目的是方便地使用tuple。
元组tuple,有人认为是std::pair扩展。pair只能把2个数据打包,而tuple可以打包更多的数据,虽然超过了9个时,其方式就比较搞笑了。
template<class _Ty1,
class _Ty2>
struct pair
{ // store a pair of values
typedef pair<_Ty1, _Ty2> _Myt;
typedef _Ty1 first_type;
typedef _Ty2 second_type;
pair()
: first(), second()
{ // default construct
}
pair(const _Ty1& _Val1, const _Ty2& _Val2)
: first(_Val1), second(_Val2)
{ // construct from specified values
}
template<class _Other1,
class _Other2,
class = typename enable_if<is_convertible<const _Other1&, _Ty1>::value
&& is_convertible<const _Other2&, _Ty2>::value,
void>::type>
pair(const pair<_Other1, _Other2>& _Right)
: first(_Right.first), second(_Right.second)
{ // construct from compatible pair
}
//......
为生成pair, c++ 提供了make_pair的快捷操作。
而tuple的定义:
template<class _This,
class... _Rest>
class tuple<_This, _Rest...>
: private tuple<_Rest...>
{ // recursive tuple definition
public:
typedef _This _This_type;
typedef tuple<_This, _Rest...> _Myt;
typedef tuple<_Rest...> _Mybase;
static const size_t _Mysize = 1 + sizeof...(_Rest);
tuple()
: _Mybase(),
_Myfirst()
{ // construct default
}
template<class... _Rest2>
explicit tuple(_Tuple_alloc_t, _Rest2&&... _Rest_arg)
: _Mybase(_STD forward<_Rest2>(_Rest_arg)...),
_Myfirst(allocator_arg)
{ // construct smuggled allocator_arg_t element
}
template<class... _Other,
class = typename _Tuple_enable<
tuple<const _Other&...>, _Myt>::type>
tuple(const tuple<_Other...>& _Right)
: _Mybase(_Right._Get_rest()), _Myfirst(_Right._Myfirst._Val)
{ // construct by copying same size tuple
}
// ....
相应地,c++ 标准库提供了make_tuple 内联方法,快速创建tuple对象。
一般std::tie有2个作用:
使用极为简单,可以使用构造函数,内联快捷方法。
示例:
// 定义时 初始化
std::tuple<int, double, std::string> student1 = { 1, 98.0, "David" };
// 使用构造函数
std::tuple<int, double, std::string> student2 ( 2, 99.2, "david2" );
下面的示例使用内联快捷方法。 这里还使用了新版本c++支持的类型auto
, 让编译器自动判断类型 – 虽然传统的我并不喜欢-- 编译时,编译器要选择至少支持C11版本. 如果使用VS,可以看到这些设置。
在linux/macOS上,在g++ build时,指定std, 如:
g++ tuple_sample.cpp -o tuple_sample -std=c++11
代码示例:
auto student2 = std::make_tuple(11, 98, "Tom" );
使用std:tie
,则也可以简单处理:
string name3 = "david3";
int id3 = 3;
double d3 = 99.3;
tuple<int, double, string> student3 = std::tie(id3, d3, name3);
使用std::tie
可以对一些集合类型进行解包,包括set, tuple, pair … 简化数据访问并赋值到变量。
如示例:
int id3;
string name3;
std::tie(id3, std::ignore, name3) = student3;
cout << "tie student-" << id3 << " \t " << name3 << endl;
注意: 这里使用std:ignore跳过数据对象中不关心的数据。
输出:
tie student-3 david3