向量作为键在C ++内部如何工作?


14

该SO回答说,带有向量作为密钥STL映射,该向量可用作密钥。因此,当我们使用向量作为键时。由于键需要唯一,因此该键实际如何工作,因此当我们插入具有相同元素的另一个向量时,将map检查逐个元素重复还是向量名称确实指定了某些东西?就像数组的名称代表基地址一样。因此,可以将数组用作键,因为在这种情况下基地址可以用作键,但是在向量的情况下,键是什么。它是如何在内部工作的。

因为当我打印矢量的名称时,我确实得到了一个错误

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

打印矢量名称是什么意思?
巴特

has operators == and <有什么帮助?我的问题是检查重复元素是否会按元素映射比较矢量键元素
Pulkit Bhatnagar

3
@PulkitBhatnagar但是......没有人会强迫你使用std::vector的关键std::map您为使用的商品付费。可以做到的,也许有一些用例,但是最确定的是您可以更改选择的数据结构。STL容器的设计具有最大的通用性,并且可以以用户可能希望使用的任何方式使用。
Yksisarvinen

1
@PulkitBhatnagar例如,请参见为什么将std :: map实现为红黑树?
Daniel Langr

1
@PulkitBhatnagar直接存储。std::map会将键和值复制到自身中。std::unordered_map可以存储密钥的哈希值。
Yksisarvinen

Answers:


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

因此,该类可用作map中的键。

默认情况下,类模板映射使用函数对象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 ++问题中都看到了您的答案,我不知道我一生是否能够实现您所拥有的,但是我会尽力而为。感谢您的回答
Pulkit Bhatnagar

8

对象的名称和该对象的内容始终是无关的事物。

operator ==for std::vector将首先比较向量的长度,然后再使用它的每个元素operator ==

operator <按字典顺序比较向量中的元素,即返回x[i] < y[i]向量x和中的第一个非相等元素y

这些是std::map用作的类型的要求Key。由于同时std::vector满足这两个条件,因此可以用作Key。请注意,由vector管理的类型还必须使这些运算符重载才能正常工作(因为std::vector依靠这些运算符来实现它自己的运算符)。

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.