【问题标题】:Why is std::pair<A,B> not the same as std::tuple<A,B>? (Is there really no way?)为什么 std::pair<A,B> 与 std::tuple<A,B> 不同? (真的没有办法吗?)
【发布时间】:2016-02-11 23:38:24
【问题描述】:

为什么std::pair&lt;A,B&gt;std::tuple&lt;A,B&gt; 不一样?不能只用一个代替另一个总是感觉很奇怪。它们在某种程度上是可转换的,但有一些限制。

我知道std::pair&lt;A,B&gt;需要有A firstB second这两个数据成员,所以不能只是std::tuple&lt;A,B&gt;的类型别名。但我的直觉告诉我们,我们可以专门化std::tuple&lt;A,B&gt;,这是一个正好有两个元素的元组,等于标准要求std::pair 的定义。然后将其别名为std::pair

我想这是不可能的,因为它太简单了以至于没有想到,但它并没有在 g++ 的 libstdc++ 中完成(我没有查看其他库的源代码)。这个定义的问题是什么?是否“只是”会破坏标准库的二进制兼容性?

【问题讨论】:

  • @Revolver_Ocelot Modern tuple 实现不是递归的。
  • @leemes 如果你想要pair,请将你的东西声明为pairs。如果您想让事情更通用,无论如何都不能使用firstsecond。 IE。这一切的目的是什么?
  • @leemes 您的草图完全无法编译,以防您没有注意到。沿着这些思路的任何事情都会使从tuple&lt;Ts...&gt; 中推断出模板参数是不可能的。
  • std::pair 已经是 C++98 的 bean 部分,std::tuple(但没有可变参数模板)随 TR1 一起提供。当时,由于多种原因,无法将具有 2 个元素的 tuple 别名为 pairC++11 附带模板别名和可变参数模板。即使有了这个,你也不能在不破坏一些现有代码的情况下将 pairtuple 的特化合并。
  • TR1 的 tuple 和 C++11 的 tuple 不需要相同——这就是 TR1 的重点。

标签: c++ c++11 stl tuples


【解决方案1】:

您必须小心 SFINAE 和超载等问题。例如,下面的代码目前格式正确,但您会将其设为非法:

void f(std::pair<int, int>);
void f(std::tuple<int, int>);

目前,我可以通过重载解析、SFINAE、模板专业化等来消除对和元组之间的歧义。如果你把它们做成相同的东西,这些工具都将无法区分它们。这会破坏现有代码。

可能有机会将它作为 C++11 的一部分引入,但现在肯定没有。

【讨论】:

  • 这个答案是最容易理解的——您解释了如果我们现在更改它会如何破坏兼容性。我想有可能在 C++11 中引入一个元组,它在有两个元素时是成对兼容的(在我描述它的意义上)。
【解决方案2】:

这纯粹是历史性的。 std::pair 自 C++98 以来就存在,而 tuple 紧随其后并且最初不是标准的一部分。

向后兼容是 C++ 进化的最大负担,阻碍了一些美好的事情轻松完成!

【讨论】:

    【解决方案3】:

    我没有尝试过,现在也没有足够的带宽这样做。您可以尝试对从 sd::pair 派生的 std::tuple 进行专门化。有人请告诉我这行不通,或者是特别可怕的想法。我怀疑你会在访问器方面遇到麻烦。

    【讨论】:

    • 您只能为自己的课程专门化 std:: 模板,一般情况下不能。
    • 如果我可以专攻自己的课程,我就可以专攻标准课程。我不遵循你的推理。 TBH 我不确定它是否非常重要,所以如果你不回复也不会难过。
    • 标准明确禁止。不涉及任何推理。 (有一个基本原理;如果可以的话,它会使标准库实现复杂化)。
    猜你喜欢
    • 2021-10-06
    • 2014-03-29
    • 2016-05-24
    • 2015-09-14
    • 2019-04-30
    • 1970-01-01
    • 2020-09-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多