一、c++中的复杂数据结构

从C开始,c++发展过来也一样,在标准库中一般不支持复杂的数据结构。比如多维的数组,多键值的KV,更不用说复杂的一批的树了。其实也很好理解,c/c++作为一个底层支持语言,追求的是高效和多平台支持,这就导致无法在复杂的数据结构中对整个数据结构进行极致优化,特别是针对于特定的平台的极致优化。这也是很多大牛自己手撸一些(如跳表等)的数据结构。
用形象的话来说,STL库就是一些“短小精悍”的函数和类组成,所以就不会有特别复杂的数据结构表现出来,其实在底层还是有一些复杂数据结构(红黑树),比如map的底层实现。

二、pair和tuple

pair和tuple都是用来进行复杂数据封装的数据结构,前者类似于KV型数据库,一对一对儿的。后者可以认为是pair的扩充,可以支持更多的value在一个元素内,早期的标准是支持十个以内,而在c++11以后,可以支持更多的value。其实对于c/c++来说,可以互相封装,这样就会产生更大的组合结构,比如可以把两个Tuple组合到Pair中。
看一下STL对它们的定义:

//Defined in header <utility>
template<
    class T1,
    class T2
> struct pair;

//Defined in header <tuple>
template< class... Types >
class tuple;

对于Pair除了可以使用构造函数,STL提供了一个便捷的方式std::make_pair<>来创建,一般也推荐这么操作。pair提供了交换、比较等常见的操作,使用越来还是比较方便的。对tuple来说,STL称它为不定长值组,它比pair要复杂,但可以转到std::tie。这个std::tie是一个tuple 的左值引用,它比较有意思。tuple也提供了一个std::make_tuple<>来创建,有一就有二嘛。同时它还提供一个tuple_cat()函数,看名字都知道可以把多个tuple连接在一起,这个在特定的场合下很有用。
同样,在c++11以后可以使用initializer list(初始化列表)来实现整体的赋值构造。pair和tuple可以通过相关的构造函数来实现转换,但看上去使用仍然不是很灵活。

三、例程

先看一下pair的例程:

#include <iostream>
#include <utility>
#include <functional>
 
int main()
{
    int n = 1;
    int a[5] = {1, 2, 3, 4, 5};
 
    // build a pair from two ints
    auto p1 = std::make_pair(n, a[1]);
    std::cout << "The value of p1 is "
              << "(" << p1.first << ", " << p1.second << ")\n";
 
    // build a pair from a reference to int and an array (decayed to pointer)
    auto p2 = std::make_pair(std::ref(n), a);
    n = 7;
    std::cout << "The value of p2 is "
              << "(" << p2.first << ", " << *(p2.second + 2) << ")\n";
}

运行结果:

The value of p1 is (1, 2)
The value of p2 is (7, 3)

再看看tuple:

#include <iostream>
#include <tuple>
#include <functional>
 
std::tuple<int, int> f() // this function returns multiple values
{
    int x = 5;
    return std::make_tuple(x, 7); // return {x,7}; in C++17
}
 
int main()
{
    // heterogeneous tuple construction
    //std::tuple<int, int>{1, -1}; // initializer list
    int n = 1;
    auto t = std::make_tuple(10, "Test", 3.14, std::ref(n), n);
    n = 7;
    std::cout << "The value of t is "  << "("
              << std::get<0>(t) << ", " << std::get<1>(t) << ", "
              << std::get<2>(t) << ", " << std::get<3>(t) << ", "
              << std::get<4>(t) << ")\n";
 
    // function returning multiple values
    int a, b;
    std::tie(a, b) = f();
    std::cout << a << " " << b << "\n";
}

运行结果:

The value of t is (10, Test, 3.14, 7, 1)
5 7
  • 相关例程来自cppreference.com

四、总结

这两个数据结构是挺简单的一个应用,传统的程序员一般会自己封装一些数据结构来实现类似的功能。不过STL中实现的东西,多少都是很多大牛们审过的,拿出来搞一搞事情,也可以接受。还是那句话,要善于学习,不要固步自封,这才是进步的动力和源泉。
在这里插入图片描述

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐