• Log in
Anwen  Share and Create
  • Book
  • Movies
  • Music
  • SF
  • Goodlink
  • Asks
  • Eyeopen
  • Create

std::tuple 实现原理以及反序存储

Sharer: 阅微堂 November 14, 2019 at 11:00 pm
Link Share :https://zhiqiang.org/coding/std-tuple.html - via RSS

std::tuple的原理并不复杂,但有些细节非常有意思。其中有一个是至少在gnu C++ std的实现中,std::tuple是倒序存储的:

std::tuple<int, int> ii;
std::cout << (&std::get<0>(ii)) < (&std::get<1>(ii)) << std::endl;  // output false

很多人都以为它就是下面这样简单实现的:

template<typename Head, ...typename Tail>
my::tuple : private my::tuple<...Tail> {
    Head head;
};

但这个实现有个问题,空类也会占用一个字节的空间!这和std::tuple的实际表现不符。具体可以参考下面代码:

struct Empty { };

int main() {
  std::cout << sizeof(std::tuple<double, Empty>) << std::endl;  // 8
  std::cout << sizeof(my::tuple<double, Empty>) << std::endl;  // 16
} 

为了达到省去空类的占用空间,std::tuple的所有成员都是继承出来的。这利用了 C++的一个特性:继承空类不会增加子类的空间。

template<std::size_t _Idx, typename _Head, typename... _Tail>
struct _Tuple_impl<_Idx, _Head, _Tail...> 
    : public _Tuple_impl<_Idx + 1, _Tail...>, private _Head_base<_Idx, _Head>
{ }

template<typename... _Elements>
class tuple : public _Tuple_impl<0, _Elements...> 
{ }

也就是说std::tuple<int, double, char>基本相当于:

std::tuple<int, double, char>
    : private _Head_base<2, char>, private _Head_base<1, double>, private _Head_base<0, int>
{}

而_Head_base只是对元素的一个简单封装:

template<std::size_t _Idx, typename _Head>
struct _Head_base<_Idx, _Head, false> {
    _Head value;
};

但它对空类做了一个特殊处理,使得封装后还是空类(注意上面的实现并没有得到空类):

template<std::size_t _Idx, typename _Head, bool = __empty_not_final<_Head>::value>
struct _Head_base;

// 此时 _Head 为空类。
template<std::size_t _Idx, typename _Head>
struct _Head_base<_Idx, _Head, true> : public _Head
{ }

由此可见,std::tuple的确是倒序存储的。但为什么它要这么做呢?【待续】

作者暂无likerid, 赞赏暂由本网站代持,当作者有likerid后会全部转账给作者(我们会尽力而为)。

Tips: Until now, everytime you want to store your article, we will help you store it in Filecoin network. In the future, you can store it in Filecoin network using your own filecoin.


Support author:
Author's Filecoin address:
Or you can use Likecoin to support author:
tags:编程 C++ C++标准库

0 0

2012-2018 Anwen All of our posts are default licensed under CC BY 4.0 About Help Changelog Telegram
Today Quote: 法律必须被信仰,否则形同虚设。 -- 伯尔曼