基本使用
cpp
#include<tuple>
using namespace std;
int main()
{
tuple<int, string, int> t(1,string("apple"),2);
//这样创建避免写类型
auto t1 = make_tuple(2,5,'a');
cout << get<0>(t) << endl;
cout << get<1>(t) << endl;
cout << get<2>(t) << endl;
cout << get<0>(t1) << endl;
cout << get<1>(t1) << endl;
cout << get<2>(t1) << endl;
//tie用于提取tuple中的属性
int x, y; string s;
tie(x, s, y) = t;
cout << x << endl;
cout << s << endl;
cout << y << endl;
//更加简单的属性提取方式
auto [a, b, c] = t;
cout << a << endl;
cout << b << endl;
cout << c << endl;
}
手搓tuple
cpp
//tuple的原版本
template<class...Args>
class tuple
{
public:
};
//这是tuple的特化版本,表示至少有一个非空模版参数
template<class T,class...Args>
class tuple<T,Args...> : private tuple<Args...>
{
private:
T _value;
public:
tuple(T x,Args... args)
:tuple<Args...>(args...),
_value(x)
{}
template<size_t n>
auto& get()
{
if constexpr (n == 0) { return _value; }
else
{
return tuple<Args...>::template get<n-1>();
}
}
};
//利用递归模版实例化+类继承机制来让tuple类有多个父类,每个父类都存放tuple中给的一个属性
//get函数就是递归调用父类的get
int main()
{
tuple<int,char,int> t(1,'x',2);
std::cout << t.get<0>() << std::endl;
std::cout << t.get<1>() << std::endl;
std::cout << t.get<2>() << std::endl;
}
**我们的get函数是使用编译时期递归模版实例化来实现,由于tuple的不同值的类型可能是不同的,就会造成这样的困境:if分支返回int,else分支推导出来其实是返回char,那么auto究竟是什么类型。**constexpr在这里的作用非常关键,当一个分支被constexpr修饰,那么只要编译时期确定了n不为0,这个分支就不会被编译,从而解决了返回值类型歧义。