天天看点

【C/C++学习笔记】C++11 tuple 元组 和 array 数组(TR1)tuplearray

tuple

类模板 

std::tuple

 是固定大小的异类值汇集,支持空列表。它是 std::pair 的推广。

若 std::is_trivially_destructible<Ti>::value 对 

Types

 中的每个 

Ti

 为 true ,则 

tuple

 的析构函数为平凡。

可以把他当做一个通用的结构体来用,不需要创建结构体又能获取结构体的特征,在某些情况下可以取代结构体使程序更简洁,直观。

基本用法

构造一个tuple

// 声明的时候使用构造函数直接初始化
std::tuple<int, double, string> item(1, 1.2, "test");
// 使用关键字 std::make_tuple
std::tuple<int, double, string> item = std::make_tuple(1, 1.2, "test");
           

 这个tuple 类似结构体

struct myStruct
{
    int a;
    double b;
    string c;
};
           

tuple的取值

// 方式一使用 get 取值
    auto temp1 = get<0>(item);
    auto temp2 = get<1>(item);
    auto temp3 = get<2>(item);
    std::cout << temp1 << std::endl;
    std::cout << temp2 << std::endl;
    std::cout << temp3 << std::endl;

    // 方式二 通过std::tie解包tuple
    int a;
    double b;
    string c;
    std::tie(a, b, c) = item;
    std::cout << "a=" << a << "   b=" << b << "   c=" << c << std::endl;
           

获取tuple长度

int nSize = std::tuple_size<decltype(item)>::value;
           

因为tuple的参数是变长的,也没有for_each函数,如果我们想遍历tuple中的每个元素,需要自己写代码实现。比如我要打印tuple中的每个元素。

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";
}
           

最后附上完整的测试代码 

#include <iostream>
#include <tuple>
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";
}

int main()
{
    //tuple<int, double, string> item(1, 1.2, "test");
    tuple<int, double, string> item = make_tuple(1, 1.2, "test");
    // 获取tuple元素个数(tuple长度)
    int nSize = std::tuple_size<decltype(item)>::value;

    PrintTuple(item);

    auto temp1 = get<0>(item);
    auto temp2 = get<1>(item);
    auto temp3 = get<2>(item);
    std::cout << temp1 << std::endl;
    std::cout << temp2 << std::endl;
    std::cout << temp3 << std::endl;

    int a;
    double b;
    string c;
    std::tie(a, b, c) = item;
    std::cout << "a=" << a << "   b=" << b << "   c=" << c << std::endl;

    system("pause");
    return 0;
}
           

array

std::array

 是封装固定大小数组的容器。

std::array除了有传统数组支持随机访问、效率高、存储大小固定等特点外,还支持迭代器访问、获取容量、获得原始指针等高级功能。而且它还不会退化成指针T *给开发人员造成困惑。

传统的数组操作就不做示例了,简单举几个array作为容器的操作:

#include <iostream>
#include <array>
using namespace std;
int main()
{
    // 用聚合初始化构造
    std::array<int, 3> a1{ {1, 2, 3} };   // CWG 1270 重申前的 C++11 中要求双花括号
                                          // ( C++11 之后的版本和 C++14 起不要求)
    std::array<int, 3> a2 = { 1, 2, 3 };  // = 后决不要求
    std::array<std::string, 2> a3 = { std::string("a"), "b" };

    // 支持容器操作
    std::sort(a1.begin(), a1.end());
    // 将 a2 反转并用空格隔开输出
    std::reverse_copy(a2.begin(), a2.end(),
        std::ostream_iterator<int>(std::cout, " "));
    std::cout << '\n';

    // 支持带范围 for 循环
    for (const auto& s : a3)
        std::cout << s << ' ';
    system("pause");
    return 0;
}