tuple是一个固定大小的不同类型值的集合,是泛化的std::pair。和c#中的tuple类似,但是比c#中的tuple强大得多。我们也可以把他当做一个通用的结构体来用,不需要创建结构体又获取结构体的特征,在某些情况下可以取代结构体使程序更简洁,直观。
#include<windows.h>
#include<string>
#include <cstdarg>
#include <set>
#include <iostream>
#include <tuple>
#include <map>
#include < utility >
using namespace std;
///
template<class Tuple, std::size_t N>
struct TuplePrinter {
static void print(const Tuple& t)
{
TuplePrinter<Tuple, N - 1>::print(t);
std::cout << ", " << std::get<N - 1>(t);
}
};
template<class Tuple>
struct TuplePrinter<Tuple, 1> {
static void print(const Tuple& t)
{
std::cout << std::get<0>(t);
}
};
template<class... Args>
void PrintTuple(const std::tuple<Args...>& t)
{
std::cout << "(";
TuplePrinter<decltype(t), sizeof...(Args)>::print(t);
std::cout << ")\n";
}
///
namespace detail
{
template<int I, typename T, typename... Args>
struct find_index
{
static int call(std::tuple<Args...> const& t, T&& val)
{
return (std::get<I - 1>(t) == val) ? I - 1 :
find_index<I - 1, T, Args...>::call(t, std::forward<T>(val));
}
};
template<typename T, typename... Args>
struct find_index<0, T, Args...>
{
static int call(std::tuple<Args...> const& t, T&& val)
{
return (std::get<0>(t) == val) ? 0 : -1;
}
};
}
template<typename T, typename... Args>
int find_index(std::tuple<Args...> const& t, T&& val)
{
return detail::find_index<0, sizeof...(Args)-1, T, Args...>::
call(t, std::forward<T>(val));
}
int main()
{
//创建元组,用std::tie,它会创建一个元组的左值引用
{
int param1 = 1;
char* param2 = "abc";
std::string param3 = "hello,world!";
auto tp = std::tie(param1, param2, param3);
//获取值
int data1 = std::get<0>(tp);
const char* data2 = std::get<1>(tp);
std::string data3 = std::get<2>(tp);
std::cout << data1 << ", " << data2 << ", " << data3 << std::endl;
//tie解包后赋值
int x = 0;
string y, z = "null";
//用std::ignore占位符来表示不解某个位置的值,只解第三个值
std::tie(std::ignore, std::ignore, z) = tp;
std::cout << x << ", " << y << ", " << z << std::endl;
//解所有值
std::tie(x, y, z) = tp;
std::cout << x << ", " << y << ", " << z << std::endl;
}
{
//创建右值的引用元组方法:forward_as_tuple
//它实际上创建了一个类似于std::tuple<int&&, std::string&&>类型的tuple
std::map<int, std::string> m;
m.emplace(std::piecewise_construct,
std::forward_as_tuple(10),
std::forward_as_tuple(20,
'a'));
}
{
std::tuple<int, std::string, double> t1(10, "Test",
3.14);
int n = 7;
//通过tuple_cat连接多个tupe
auto t2 = std::tuple_cat(t1, std::make_pair("Foo",
"bar"), t1, std::tie(n));
n = 10;
using mult_tuple = std::tuple<int, std::string, double, std::string, std::string, int, std::string, double, int>;
TuplePrinter<mult_tuple,9>::print(t2);
cout << endl;
}
{
//创建方式一:一个元素是引用的元组
std::tuple<int, std::string, double> mytuple(10, "Test", 3.14);
//创建方式二:使用make_tuple创建元组
auto mytuple2 = std::make_tuple(10, "Test", 3.14);
//获取tuple中元素的个数
int size = std::tuple_size<decltype(mytuple2)>::value;
std::cout << "mytuple contains element's number:" << size << endl;
//通过std::tuple_element获取元素类型
std::tuple_element<0, decltype(mytuple)>::type first = std::get<0>(mytuple);
std::tuple_element<1, decltype(mytuple)>::type second = std::get<1>(mytuple);
std::tuple_element<2, decltype(mytuple)>::type third = std::get<2>(mytuple);
std::cout << "mytuple contains: " << first << " and " << second << " and " << third << endl;
}
{
//根据tuple元素值获取其对应的索引位置
std::tuple<int, int, int, int> a(2, 3, 1, 4);
int iTemp = 1;
std::cout << find_index(a, iTemp) << std::endl; // Prints 2
iTemp = 2;
std::cout << find_index(a, iTemp) << std::endl; // Prints 0
iTemp = 5;
std::cout << find_index(a, iTemp) << std::endl; // Prints -1 (not found)
}
system("pause");
return 0;
}