std :: pairとstd :: tupleのメンバーが2つしかない場合の違いは?


92

間に差があるstd::pairと、std::tuple2人のだけのメンバーとは?(std::pair2つだけのメンバーを必要としtuple、多かれ少なかれ持っているかもしれないという明白なことに加えて...)

回答:


86

いくつかの違いがあります:

  1. std::tuple標準レイアウトによるものにすることはできません(少なくとも、標準によるものである必要はありません)。とがstd::pair<T, Y>両方とも標準レイアウトである場合、すべてが標準レイアウトです。TY

  2. の内容を取得するpair方がtuple。よりも少し簡単です。ケースは単なるメンバーフィールドですがtuplepairケースでは関数呼び出しを使用する必要があります。

しかし、それはそれについてです。


5
「タプルよりもペアからデータを取得する方が少し簡単です。少し。」私は気づきました。:P.first.secondは便利ですが、コードの変更で3番目(またはそれ以上)のメンバーが必要な場合は役に立ちません。std::getゲッターに関係なく、すべてを変更する必要はなく、データ型とmake_pair呼び出しの呼び出しだけを変更する必要があることに気づきましたmake_tuple
ケーシー

これは、その表示されたstd::map用途をstd::pair<const Key,T>としてvalue_typeも、C ++ 11インチ タプルはどこで使用されていstd::mapますか?
nknight 2012

@nknight:...なぜそう言ったのかわかりません。または、の代わりに私が言いたかったことstd::map
ニコルボーラス2012

1
@Yakk:ええと、私は「。」を押します 私のIDEはメンバーのリストを表示します。私は人々がそれを詳しく説明する必要があるとは思いませんでした。
ニコルボーラス2016年

2
c ++ 17の構造化バインディングは、この回答の1ポイントと2ポイントの両方をすでに無効にしているのでしょうか。もしそうなら、これのc ++ 17バージョンも追加してください。
サンドソーン2018年

29

これは、ことが非常に遅く答えが、ノートであるstd::pairメンバ変数で定義され、そのサイズは使用して最適化することができない空の基底クラスの最適化をfirstそしてsecond一方または両方が空クラスの場合でも、個別のアドレスを占有しなければなりません)。これsecond_typeは、アライメント要件が何であれ悪化するため、最悪の場合、結果としてstd::pairは基本的に必要なサイズの2倍になります。

std::tupleヘルパー関数を介したアクセスのみを許可するため、どちらかが空の場合はどちらのタイプからも派生でき、オーバーヘッドを節約できます。GCCの実装は、少なくとも、間違いなくこれを行います...ヘッダーを調べてこれを確認できますが、証拠としてこれもあります。


4
もちろん、C ++ 20[[no_unique_address]]std::pairはの欠点を取り除くはずです。
デュプリケータ

「std :: tupleはヘルパー関数を介したアクセスのみを許可します」、またはC ++ 17構造化バインディング。非常に多くの合理的なC ++の回答が、最近すぐに古くなっているのは悲しいことです。:-(
cosimo193

29

アンstd::tupleの名前が長い(1つの余分な文字)です。これらの文字の多くは右手で入力されるため、ほとんどの人が簡単に入力できます。

とはstd::pairいえ、値は2つだけで、0、1、3、またはそれ以上にすることはできません。2つの値。ただし、タプルには、値の数に意味上の制限はほとんどありません。アンはstd::pair、したがって、あなたが実際の値のペアを指定したい場合に使用する安全なタイプを入力し、より正確です。


20
笑!あなたがそれがどのようにタイプされるかを考えることは素晴らしいです!私はおそらく「タプル」よりも20%以上速く「ペア」と入力することを指摘したいと思います。これは、私の手が各文字を交互に入力するためです。RHS:p、LHS:a、RHS:i、LHS:r。少なくとも私にとっては、それが簡単だと思います!-しかし、あなたはまだ+1を得る!
リチャードコーデン2011

15
したがって、std :: pairは、実際に値のペアを指定する場合に使用する、より正確でタイプセーフなタイプです。」これは、タイプセーフまたは「正確」ではなく、(おそらく)意図を示すだけです。より直接的に。
ildjarn 2012

1
@Arafangion:std::tuple<>ありませんまた、タイプセーフ(?それはどのようになることができませんでした)、そして2何よりも意味的に異なっていますpair
ildjarn 2012

1
したがって、std :: pairは、より正確でタイプセーフなタイプです」そして、英語を話す人なら誰でも、「pair」と「two」を完全に同義語と考えるでしょう。:-]
イルジャーン2012

5
@ildjam:ここではヘアを分割していますが、いいえ、完全に同義ではありません。「2つの靴」とは、「2つの靴、どちらも左の靴である可能性が高い」という意味ですか、それとも「1足の靴」(一方は常に左で、もう一方は常に右)を意味します。 ?
アラファンギオン2012

9

C ++ 17では、同じインターフェイスを使用して、2つの要素を持つペアとタプルの両方からデータを読み取ることができることに注意してください。

auto [a, b] = FunctionToReturnPairOrTuple();

使用する必要はありませんget<>:)


3

std :: tupleのGDB出力は、はるかに読みにくいと思います。明らかに、3つ以上の値が必要な場合、std :: pairは機能しませんが、これは構造体に有利な点だと思います。


そのため、クラスでそれらを使用するときは、グロスラインstd::get<0>(tupleName)をゲッターでラップします。GetX()はるかに読みやすく、短いです。それをconstメソッドにするのを忘れた場合、誰かが次のような愚かなことをする可能性があるという小さな欠点がありますGetX() = 20;
ケーシー
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.