Как вектор как ключ работает внутри C ++? - PullRequest
14 голосов
/ 17 февраля 2020

В этом ответе SO говорится, что Карта STL с вектором для ключа вектор может использоваться в качестве ключа. Поэтому, когда мы используем вектор в качестве ключа. Как это на самом деле работает, так как ключ должен быть уникальным, поэтому, когда мы вставляем другой вектор с такими же элементами, map проверяет наличие дублирующихся элементов за элементом, или имя вектора что-то указывает? Как имя массива представляет базовый адрес. Таким образом, массив может быть использован в качестве ключа, так как базовый адрес может быть использован в качестве ключа в этом случае, но каков ключ в случае вектора. Как это работает внутри.

Потому что, когда я печатаю имя вектора, я получаю ошибку

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

Ответы [ 2 ]

9 голосов
/ 17 февраля 2020

Существует перегруженный оператор <для шаблона класса std :: vector. </p>

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, который в свою очередь использует оператор <</p>

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

Однако перегруженного оператора << для шаблона класса std :: vector нет. </p>

8 голосов
/ 17 февраля 2020

Имя объекта и содержимое этого объекта всегда не связаны между собой.

operator == для std::vector сначала сравнивает длину векторов, а затем каждый из его элементов, используя operator ==.

operator < сравнивает элементы в векторе лексикографически, то есть возвращает x[i] < y[i] для первого неравного элемента в векторах x и y.

Это требования std::map имеет для типа, используемого как Key. Поскольку std::vector удовлетворяет обоим условиям, его можно использовать как Key. Обратите внимание, что для типа, управляемого вектором, эти операторы также должны быть перегружены, чтобы это работало (поскольку std::vector полагается на эти операторы для реализации своих собственных операторов).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...