Как вектор как ключ работает внутри C ++?

14

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

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

vector<int> v;
cout<<v; //error
Пулькит Бхатнагар
источник
Что вы имеете в виду, печатая векторное имя?
Барт
has operators == and <как это поможет? мой вопрос состоял в том, чтобы проверить дубликаты элементов, сопоставить сопоставление ключевого элемента вектора с элементом
Pulkit Bhatnagar
3
@PulkitBhatnagar Но ... Никто никогда не заставит вас использовать в std::vectorкачестве ключа для std::map. Вы платите за то, что используете . Это можно сделать, и, возможно, для этого есть несколько вариантов использования, но, безусловно, вы можете изменить предпочитаемую структуру данных. Контейнеры STL спроектированы так, чтобы быть максимально универсальными и удобными для использования любым способом, который пользователь может захотеть использовать.
Иксисарвинен
1
@PulkitBhatnagar Посмотрите, например, почему std :: map реализован как красно-черное дерево? ,
Даниэль Лангр
1
@PulkitBhatnagar Магазины напрямую. std::mapскопирует ключ и значение в себя. std::unordered_mapможет хранить хэш ключа.
Иксисарвинен

Ответы:

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, я не знаю, смогу ли я когда-нибудь за всю свою жизнь достичь того, что у вас есть, но я буду стараться изо всех сил. Спасибо за ответ
Пулькит Бхатнагар
8

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

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

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

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

Yksisarvinen
источник