キーとしてのベクトルは、C ++で内部的にどのように機能しますか?


14

このSOの答えは、キーのベクトルを持つSTLマップ、ベクトルをキーとして使用できることを示しています。したがって、ベクターをキーとして使用する場合。キーは一意である必要があるため、実際にはどのように機能mapしますか?同じ要素を持つ別のベクターを挿入すると、要素ごとに重複した要素がないかチェックされますか、ベクターの名前が何かを指定していますか?配列の名前と同様に、ベースアドレスを表します。したがって、この場合はベースアドレスをキーとして使用できるため、配列をキーとして使用できますが、ベクトルの場合はキーは何ですか。内部ではどのように機能しますか。

ベクトルの名前を出力するとエラーになるので

vector<int> v;
cout<<v; //error

ベクター名を印刷するとはどういう意味ですか?
バート

has operators == and <それはどのように役立ちますか?私の質問は、重複する要素をマップして要素
ごとに

3
@PulkitBhatnagarしかし... ...のstd::vectorキーとして使用することを強制する人は誰もいませんstd::map使用した分だけお支払いいただきます。それは可能であり、おそらくいくつかのユースケースがありますが、選択したデータ構造を変更することができます。STLコンテナーは、最大限に用途が広く、ユーザーがコンテナーを使用したい方法で使用できるように設計されています。
Yksisarvinen

1
@PulkitBhatnagarたとえば、std :: mapが赤黒木として実装されている理由を参照してください
Daniel Langr

1
@PulkitBhatnagar Stores直接。std::mapキーと値の両方をそれ自体にコピーします。std::unordered_mapキーのハッシュを保存できます。
Yksisarvinen

回答:


9

クラステンプレートstd :: vectorにはオーバーロードされた演算子<があります。

template <class T, 
class Allocator>
bool operator< (const vector<T, Allocator>& x, const vector<T, Allocator>& y);

これは標準アルゴリズムに基づいていますstd::lexicographical_compare

ここにデモプログラムがあります。

#include <iostream>
#include <iomanip>
#include <vector>
#include <iterator>
#include <algorithm>

int main() 
{
    std::vector<int> v1 = { 1, 2 };
    std::vector<int> v2 = { 1, 2, 3 };
    std::vector<int> v3 = { 2 };

    std::cout << std::boolalpha << ( v1 < v2 ) << '\n';
    std::cout << std::lexicographical_compare( std::begin( v1 ), std::end( v1 ),
                                               std::begin( v2 ), std::end( v2 ) )
             << '\n';                                              

    std::cout << std::boolalpha << ( v1 < v3 ) << '\n';
    std::cout << std::lexicographical_compare( std::begin( v1 ), std::end( v1 ),
                                               std::begin( v3 ), std::end( v3 ) )
             << '\n';                                              

    std::cout << std::boolalpha << ( v2 < v3 ) << '\n';
    std::cout << std::lexicographical_compare( std::begin( v2 ), std::end( v2 ),
                                               std::begin( v3 ), std::end( v3 ) )
             << '\n';                                              

    return 0;
}

その出力は

true
true
true
true
true
true

そのため、クラスはマップのキーとして使用できます。

デフォルトでは、クラステンプレートマップは関数オブジェクトstd :: lessを使用し、次に演算子<を使用します

template <class Key, class T, class Compare = less<Key>,
class Allocator = allocator<pair<const Key, T>>>
class map 
{
    //...
};

ただし、クラステンプレートstd :: vectorのオーバーロードされた演算子<<はありません。


5
最近、SOのほとんどすべてのC ++の質問であなたの答えがわかります。私の人生の中で、あなたが持っているものを達成できるかどうかはわかりませんが、最善を尽くします。答えてくれてありがとう
プルキットバトナガール

8

オブジェクトの名前とそのオブジェクトのコンテンツは、常に無関係です。

operator ==for std::vectorは最初にベクトルの長さを比較し、次に各要素operator ==も同様に使用して比較します。

operator < ベクトルの要素を辞書式に比較します。つまり、 x[i] < y[i]、ベクトルxとの最初の等しくない要素をy

これらは、std::mapとして使用されるタイプの要件ですKeystd::vector両方を満たすので、asで使用できますKey。これが機能するためにstd::vectorは、vectorによって管理される型にもこれらの演算子がオーバーロードされている必要があることに注意してください(独自の演算子の実装はこれらの演算子に依存しているため)。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.