只有两个成员的std :: pair和std :: tuple之间的区别?


91

只有两个成员的anstd::pair和an之间有区别std::tuple吗?(除了显而易见的std::pair要求,只有两个成员而且tuple可能有更多或更少的成员。)

Answers:


86

有一些区别:

  1. std::tuple绝不可能通过标准的布局(至少,它不是必需的是由标准)。每一个std::pair<T, Y>是标准的布局如果两个TY是标准布局。

  2. 获取a的内容pair比获取a的内容要容易一些tuple。您必须在tuple案例中使用函数调用,而pair案例只是一个成员字段。

就是这样。


4
“从数据对中提取数据要比元组容易一些。有一点。” 我注意到。:P尽管.first并且.second很方便,但是如果在代码更改中需要第三(或更多)成员,它们将不提供任何帮助。我已经注意到,std::get无论在任何Getter中,我都倾向于使用那种方式,我不需要更改所有内容,只需更改数据类型和任何make_pair调用即可make_tuple
Casey

看来,std::map用途std::pair<const Key,T>value_type即使在C ++ 11。元组到底在哪里使用std::map
nknight 2012年

@nknight:...我不知道为什么我这么说。还是我要说的而不是std::map
Nicol Bolas'8

1
@Yakk:嗯,我按“。” 我的IDE弹出一个成员列表。我认为人们并不需要这些。
Nicol Bolas

1
我想知道c ++ 17中的结构化绑定是否已经使该答案的1点和2点无效?如果是这样,也请添加一个c ++ 17版本。
桑索德18'Jan

29

一个std::tuple的名字较长(一个额外的字符)。这些字符中更多的是用右手键入的,因此对于大多数人来说更容易键入。

也就是说,std::pair只能有两个值-不能为零,一,三个或更多。两个值。但是,元组对值的数量几乎没有语义上的限制。std::pair因此,如果您实际上要指定一对值,则使用an是更准确的类型安全类型。


20
大声笑!辉煌,您考虑如何键入!我想指出的是,我输入“ pair”可能比“ tuple”快20%以上。这是因为我的手会交替键入每个字符,即。RHS:p,LHS:a,RHS:i,LHS:r。至少对我来说,这更容易做到!-但您仍然获得+1!
理查德·科登,

14
因此,如果您实际上要指定一对值,则使用std :: pair是更准确的类型安全类型。 ”它不是类型安全或“准确”的,它只是(可以说)表示意图更直接。
ildjarn

1
@Arafangion:std::tuple<>同样类型安全的(它怎么会没有呢?),并2没有比语义不同pair
ildjarn

1
因此,std :: pair是更准确的类型安全使用类型”,而且我认为任何说英语的人都会认为'pair'和'two'是完全同义词。:-]
ildjarn 2012年

4
@ildjam:我们在这里要剪头发,但是不,它们不是完全同义的。当您说“两双鞋”时,您是说“两双鞋,很可能都是左鞋”,还是说“一双鞋”(其中一双总是左,另一双总是右) ?
Arafangion

28

这是一个非常晚的答案,但需要注意的是,由于std::pair与成员变量定义,其大小不能使用优化空基类优化firstsecond必须占用不同的地址,即使一个或两个是空类)。无论second_type哪种对齐要求,这种情况都会加剧,因此在最坏的情况下,结果std::pair基本上将是所需大小的两倍。

std::tuple仅允许通过辅助函数进行访问,因此如果一个或另一个为空,则可以从任一类型派生,从而节省了开销。GCC的实现,在非常至少,绝对做到这一点...你可以通过头部捅来验证这个却也有为证。


4
当然,C ++ 20[[no_unique_address]]应该消除std::pair的缺点。
Deduplicator

“ std :: tuple仅允许通过辅助函数进行访问”或C ++ 17结构化的绑定。遗憾的是,这些天来这么多合理的C ++答案是如此之快。:-(
cosimo193

8

请注意,对于C ++ 17,可以使用同一接口从具有两个元素的对和元组中读取数据。

auto [a, b] = FunctionToReturnPairOrTuple();

无需使用get<>:)


3

对于它的价值,我发现std :: tuple的GDB输出要难得多。显然,如果您需要两个以上的值,则std :: pair将不起作用,但是我确实认为这是对结构的支持。


这就是为什么当我在课堂上使用它们时,将粗线包裹std::get<0>(tupleName)在吸气剂中。GetX()更容易阅读和缩短。它有一个小缺点,如果你忘记让它const方法有人可以做一些愚蠢这样的:GetX() = 20;
Casey
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.