Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/73.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么对std::tuple实现使用递归继承不好?_C++_C++11_Stdtuple - Fatal编程技术网

C++ 为什么对std::tuple实现使用递归继承不好?

C++ 为什么对std::tuple实现使用递归继承不好?,c++,c++11,stdtuple,C++,C++11,Stdtuple,霍华德·欣南(Howard Hinnant)表示,这是一个疑问 std::tuple的一些实现使用递归继承。但是好的就不行了 有人能解释一下吗 我不记得Andrei Alexandrescu在2012年的演讲,但他谈到了这一点,他提到的其中一点是内存布局。如果我有一个std::tuple,它将以char,short,int的形式存在于内存中,并且这种布局(在我的系统上)比以int,short,char的形式存在时多占用4个字节。他提醒我,最好的做法是在内存中按最小填充的顺序排序,这既不是给定的顺

霍华德·欣南(Howard Hinnant)表示,这是一个疑问

std::tuple的一些实现使用递归继承。但是好的就不行了


有人能解释一下吗

我不记得Andrei Alexandrescu在2012年的演讲,但他谈到了这一点,他提到的其中一点是内存布局。如果我有一个
std::tuple
,它将以
char,short,int
的形式存在于内存中,并且这种布局(在我的系统上)比以
int,short,char
的形式存在时多占用4个字节。他提醒我,最好的做法是在内存中按最小填充的顺序排序,这既不是给定的顺序,也不是相反的顺序。(天真的继承顺序正好相反)

如果我写
std::tuple
,一个通过原始继承工作的元组会在内存中使用3个字节的填充,将它们按
char,short,int
的顺序排列,而optimal的填充字节数为零。(可以是
int,short,char,char
char,char,short,int

假设我关于填充的观点是正确的,那么R.Martinho Fernandes“[我的论点]并不排除在实际实现中以最佳顺序使用递归继承”,所以这就是为什么我指定原始继承是不好的

(内存中的顺序并不意味着
get
将给出一个不同的对象,R.Martinho Fernandes正确地指出,用户应该看不到该顺序。但是,这些是我从GoingNative事件中得到的提示。)


视频在,幻灯片在。

不使用基类链的一个原因是没有涉及构造函数链:参数直接转发到相应的子对象。此外,非递归实现似乎给编译器带来的压力要小得多,创建的[内部]符号也要少得多。更不用说它实际上比基类链更容易。

具有更好的编译时性能。信不信由你,在像
std::tuple
这样的大量使用的库工具中,它的实现方式可能会影响(无论是好是坏)客户端看到的编译时间。递归实现倾向于产生在递归深度上呈线性的编译时间(甚至可能更糟)

这不仅仅影响元组本身的实例化<例如,code>std::get(tuple)将为一个实现占用线性编译时间,为另一个实现占用恒定的编译时间。在处理元组中的元组时,这种影响可能会迅速恶化(或者不会)。即,递归实现可能导致O(N^2)编译时,而非递归实现仍然是O(1)


Fwiw,libc++实现按照客户机指定的顺序排列对象,但使用编译器的空基类优化工具优化空组件的空间。

他在评论中还谈到了什么?如果元组“嵌套深度”足以让编译器负担过重,您可能需要再次查看代码。我不认为没有困难的错误信息就可以做到这一点。啊,所以不是递归继承不好,而是幼稚的递归继承?我想知道@Howard是否有其他想法,是否有另一个观点支持另一种技术。@MooingDuck:如果你有如此深的嵌套元组,那么我会说你最不想做的事情就是再看一遍你的代码……;)@MooingDuck嘿,我写了一个非常粗糙的元组实现,它总是为您提供最佳布局:。它计算最佳顺序(如果为libc++和libstdc++的实现而定义),并从标准库中包装一个元组,从而对用户隐藏真正的顺序。我仍然无法在GCC上获得所有要编译的
get
调用,但是所有的静态_断言都在传递,并且它在使用libc++的clang上运行良好。我不知道如何进行编译时性能分析,所以这可能是低效的。如果您有任何问题,请在聊天中Ping我:)可能与转发论点的效率低下有关?如果有人能概括出那些好的论点和那些好的论点之间的区别,可能会很有帮助。@Cheers:我认为内联可以解决这个问题--但话说回来,我必须承认,我遇到过一些编译器,它们断然决定停止内联深度超过3或4。这个问题(以及您的答案)促使我探索非递归元组实现。我写了一篇关于它的帖子:。如果您能抽出一点时间阅读并指出任何错误,我将不胜感激。ThanksI使用Howards实现来改进我的一个较小的程序。在测试中,我还包括了在编译时间和可执行文件大小方面改进tuple_元素的测试。令我惊讶的是,情况不但没有好转,反而恶化了。我使用的是GCC4.8.2。最新的gcc是否有优化尾部模板递归的功能?或者,上述技巧是否只适用于极端情况?是否有任何例子或成功案例证明了优化的有效性?