C++容器之元组(std::tuple)

1 概述

  元组(tuple)是将不同类型的元素打包在一个对象中的对象,就像对对象对元素对所做的那样,但对任何数量的元素都是通用的。
  从概念上讲,它们类似于普通的旧数据结构(类C结构),但没有命名的数据成员,而是按元组中的顺序访问其元素。
  元组中特定元素的选择是在模板实例化级别完成的,因此,它必须在编译时使用get和tie等辅助函数进行指定。
  元组类与pair类密切相关:元组可以由对构建,出于某些目的,pair 可以被视为元组。
  数组(array)容器还具有某些类似元组(tuple)的功能。

其类图如下:
类图

2 使用实例

void TupleSuite::get()
{
    std::tuple<int , char> a(10, 'a');
    std::get<0>(a) =  20;
    std::tuple_element<0, decltype(a)>::type b = std::get<0>(a);//b is int

    TEST_ASSERT_EQUALS(20, b)
    TEST_ASSERT_EQUALS('a', std::get<1>(a))
    TEST_ASSERT_EQUALS('b', std::get<1>(std::tuple<int , char>(10, 'b')))
} 

3 接口使用

3.1 constructor

void TupleSuite::constructor()
{
    std::tuple<int,char> a;                           // default
    std::tuple<int,char> b (a);                       // copy
    std::tuple<int,char> c (std::make_tuple(20,'b')); // move
    std::tuple<long,char> d (c);                      // implicit conversion
    std::tuple<int,char, char> e (10,'a', 'b');       // initialization
    std::tuple<int,char> f (std::make_pair(30,'c'));  // from pair / move

    TEST_ASSERT_EQUALS(2, std::tuple_size<decltype(a)>::value)
    TEST_ASSERT_EQUALS(2, std::tuple_size<decltype(b)>::value)
    TEST_ASSERT_EQUALS(2, std::tuple_size<decltype(c)>::value)
    TEST_ASSERT_EQUALS(2, std::tuple_size<decltype(d)>::value)
    TEST_ASSERT_EQUALS(3, std::tuple_size<decltype(e)>::value)
    TEST_ASSERT_EQUALS(2, std::tuple_size<decltype(f)>::value)
}

3.2 get

void TupleSuite::get()
{
    std::tuple<int , char> a(10, 'a');
    std::get<0>(a) =  20;

    TEST_ASSERT_EQUALS(20, std::get<0>(a))
    TEST_ASSERT_EQUALS('a', std::get<1>(a))
    TEST_ASSERT_EQUALS('b', std::get<1>(std::tuple<int , char>(10, 'b')))
} 

说明:

  • get函数越界后,会有参数列表匹配错误,导致编译出错。

3.3 assigns

void TupleSuite::assigns()
{
    std::pair<int, char> pair(10, 'a');
    std::tuple<int, char> a(20, 'b');
    std::tuple<int, char> b;
    std::tuple<long, char> c;
    std::tuple<long, char, char> d;
    b = a; //copy assignment
    TEST_ASSERT_EQUALS('b', std::get<1>(b))

    c = std::make_tuple(30L, 'c');//move assignment
    TEST_ASSERT_EQUALS('c', std::get<1>(c))

    a = c;//conversion assignment
    TEST_ASSERT_EQUALS(30, std::get<0>(a))

    c = std::make_tuple(30, 'd');//conversion / move assignment
    TEST_ASSERT_EQUALS('d', std::get<1>(c))

    c = pair;//from pair assignment
    TEST_ASSERT_EQUALS('a', std::get<1>(c))

    a = std::make_pair(2, 'b');//form pair /move assignment
    TEST_ASSERT_EQUALS('b', std::get<1>(a))
}

3.4 swap

void TupleSuite::swap()
{
    std::tuple<int,char> a (10,'x');
    std::tuple<int,char> b (20,'y');

    TEST_ASSERT_EQUALS(10, std::get<0>(a))
    TEST_ASSERT_EQUALS('x', std::get<1>(a))
    TEST_ASSERT_EQUALS(20, std::get<0>(b))
    TEST_ASSERT_EQUALS('y', std::get<1>(b))

    a.swap(b);
    TEST_ASSERT_EQUALS(20, std::get<0>(a))
    TEST_ASSERT_EQUALS('y', std::get<1>(a))
    TEST_ASSERT_EQUALS(10, std::get<0>(b))
    TEST_ASSERT_EQUALS('x', std::get<1>(b))

    std::swap(a, b);
    TEST_ASSERT_EQUALS(10, std::get<0>(a))
    TEST_ASSERT_EQUALS('x', std::get<1>(a))
    TEST_ASSERT_EQUALS(20, std::get<0>(b))
    TEST_ASSERT_EQUALS('y', std::get<1>(b))

}

3.4 relational

void TupleSuite::relational()
{
    std::tuple<int,char> a (10,'x');
    std::tuple<char,char> b (10,'x');
    std::tuple<char,char> c (10,'y');

    TEST_ASSERT_EQUALS(true, a == b)
    TEST_ASSERT_EQUALS(true, b != c)
    TEST_ASSERT_EQUALS(true, b < c)
    TEST_ASSERT_EQUALS(true, c > a)
    TEST_ASSERT_EQUALS(true, a <= c)
    TEST_ASSERT_EQUALS(true, c >= b)
    TEST_ASSERT_EQUALS(true, a >= b)
    TEST_ASSERT_EQUALS(true, b >= a)
}

3.4 cat

void TupleSuite::cat()
{
    std::tuple<float, std::string> a(3.14, "pi");
    std::tuple<int, char> b(10, 'a');
    auto c = std::tuple_cat(a, b);
    TEST_ASSERT_EQUALS(4, std::tuple_size<decltype(c)>::value)
    TEST_ASSERT_EQUALS(3.14f, std::get<0>(c))//3.14
    TEST_ASSERT_EQUALS("pi", std::get<1>(c))
    TEST_ASSERT_EQUALS(10, std::get<2>(c))
    TEST_ASSERT_EQUALS('a', std::get<3>(c))
}

3.4 tie

void TupleSuite::tie()
{
    std::tuple<int, float, char> a = std::make_tuple(10, 2.6, 'a');
    int i;
    char c;
    std::tie(i, std::ignore, c) = a;
    TEST_ASSERT_EQUALS(10, i)
    TEST_ASSERT_EQUALS('a', c)
}

3.4 forward

void TupleSuite::forward()
{
    auto a = std::make_tuple(10, 'a');
    auto b = std::forward_as_tuple(10, 'a');
    std::tuple<int, char> c;
    std::tuple<int &&, char &&> d(20, 'a'); 
    
    std::get<0>(a) = 20;
    std::get<0>(b) = 30;

    TEST_ASSERT_EQUALS(false, typeid(a) == typeid(b))
    TEST_ASSERT_EQUALS(true, typeid(a) == typeid(c))
    TEST_ASSERT_EQUALS(true, typeid(b) == typeid(d))
    TEST_ASSERT_EQUALS(20, std::get<0>(a))
    TEST_ASSERT_EQUALS(30, std::get<0>(b))
}

说明:

  • make_tuple构造tuple<int, char>类型tuple
  • forward_as_tuple构造tuple<int&&, char&&>类型tuple
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

flysnow010

你的鼓励就是我最大的创作动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值