Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/157.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用不同的键搜索数据 我不是C++和STL的专家。_C++_Stl - Fatal编程技术网

使用不同的键搜索数据 我不是C++和STL的专家。

使用不同的键搜索数据 我不是C++和STL的专家。,c++,stl,C++,Stl,我使用地图中的结构作为数据。钥匙是C1类的。 我希望访问相同的数据,但也使用不同的键C2(其中C1和C2是两个不相关的类) 这在不复制数据的情况下是可能的吗? 我试着在谷歌上搜索,但很难找到一个我能理解的答案 这适用于不支持boost库的嵌入式目标 有人能提供帮助吗?不在标准库中,但Boost提供了两个不同类型的键 我必须承认我读错了一点,并没有真正注意到您需要两个不同类型的键,而不是值。不过,解决方案将基于以下内容。其他答案有很多需要的,我只想补充一点,您可以创建一个通用的查找函数:(C++1

我使用地图中的结构作为数据。钥匙是C1类的。 我希望访问相同的数据,但也使用不同的键C2(其中C1和C2是两个不相关的类)

这在不复制数据的情况下是可能的吗? 我试着在谷歌上搜索,但很难找到一个我能理解的答案

这适用于不支持boost库的嵌入式目标


有人能提供帮助吗?

不在标准库中,但Boost提供了两个不同类型的键 我必须承认我读错了一点,并没有真正注意到您需要两个不同类型的键,而不是值。不过,解决方案将基于以下内容。其他答案有很多需要的,我只想补充一点,您可以创建一个通用的查找函数:(C++14 ish伪代码)

通过
数据[键[“多键”]]
访问

这显然会浪费一些空间(复制
Key
类型的对象),但我假设它们比
Data
类型小得多

想法2 另一个解决方案是使用指针;那么复制的唯一代价就是(智能)指针:

地图数据;

只要至少有一个键指向
数据的对象,该对象将处于活动状态。

在这些情况下,我通常使用非自有指针。我将数据存储在向量中:

std::vector<Data> myData;
std::vector myData;
然后我将指针映射到每个元素。由于指针可能会因为向量的未来增长而失效,所以在本例中,我将选择使用向量索引

std::map<Key1, int> myMap1;
std::map<Key2, int> myMap2;
std::map myMap1;
std::map myMap2;
不要向客户端公开数据容器。将元素的插入和删除封装在特定函数中,这些函数到处插入,到处删除。

Bartek的“想法1”很好(尽管没有令人信服的理由更喜欢
无序映射
而不是
映射

或者,您可以使用
std::map
std::map
在一次
C2
键搜索后直接访问
数据
对象,但是您需要更加小心,不要访问无效(已擦除的)
数据
(或者更准确地说,从任何其他用户的角度,以原子方式从两个容器中
擦除

一个或两个
map
s也可以移动到
shared\u ptr
——另一个可以使用
weak\u ptr
,如果这对所有权有帮助的话。(这些都在C++11标准中,否则明显的源代码boost显然不适合您,但可能您已经实现了自己的库或选择了另一个库?这是现代C++非常基本的类)

编辑-哈希表与平衡二叉树

这与问题并不特别相关,但已收到以下评论/兴趣,我需要更多的空间来适当解决。以下几点:

1) Bartek漫不经心地建议从
map
更改为
unordered_map
,而不建议进行影响研究,重新迭代/指针无效是危险的,而且没有理由认为需要(问题没有提到性能)也没有推荐进行分析

3) 程序中相对较少的数据结构对性能关键行为很重要,而且很多时候,一个与另一个的相对性能无关紧要。支持这一说法-大量代码是用
std::map
编写的,以确保C++11之前的可移植性,并且执行得很好

P> 4)当表现是一个严重的问题时,建议应该是“Cale=“Profile”,但是说一条经验法则是可以的——与“不要过早悲观”(参见萨特和Alexandrescu的C++编码标准)一致。-如果这里有人问我,我很乐意推荐默认情况下的
unordered\u map
-但这并不特别可靠。这与推荐我看到的每一种
std::map
用法相去甚远


5) 这个容器性能方面的研究已经开始引入有用见解的特别片段,但还远远不够全面或平衡。这个问题不是进行这种讨论的合理场所。如果有另一个问题可以解决这个问题,继续讨论是有意义的,并且有人让我插手,我将在下一两个月的某个时候做。

您可以将指向
数据的指针存储为
std::map
值,并且您可以有两个具有指向相同数据的不同键的映射

我认为在这种共享数据所有权的情况下,像std::shared\u ptr这样的智能指针是一个很好的选择:

#include <map>       // for std::map
#include <memory>    // for std::shared_ptr

....

std::map<C1, std::shared_ptr<Data>> map1;
std::map<C2, std::shared_ptr<Data>> map2;
#包含//用于std::map
#包含//用于std::shared\u ptr
....
地图地图1;
地图地图2;

<> > <代码>数据< /代码>可以使用<代码> STD::MaMaSyfSyd()/<代码> .< /P> < P>可以考虑有一个简单的<代码> STD::列表< /COD>保存所有的数据,然后各种<代码> STD::MAP< /COD>对象映射任意关键字值到指向列表的迭代器:

std::list<Data> values;
std::map<C1, std::list<Data>::iterator> byC1;
std::map<C2, std::list<Data>::iterator> byC2;
std::列出值;
std::map byC1;
std::map byC2;

也就是说,使用普通迭代器,而不是处理或多或少的原始指针。进入
std::list
的迭代器有很好的失效保证。

我也有同样的问题,起初为共享指针持有两个map听起来很酷。但您仍然需要管理这两个映射(插入、删除等)

然后我想出了另一种方法。 我的理由是;使用x-y或半径角度访问数据。想象一下,每个点都将保存数据,但点可以用笛卡尔x、y或半径角来描述

所以我写了一个类似

struct MyPoint
{
    std::pair<int, int> cartesianPoint;
    std::pair<int, int> radianPoint;

    bool operator== (const MyPoint& rhs)
    {
         if (cartesianPoint == rhs.cartesianPoint || radianPoint == rhs.radianPoint)
             return true;
         return false;
    }
}
struct MyPoint
{
std::成对笛卡尔点;
std::map<Key1, int> myMap1;
std::map<Key2, int> myMap2;
#include <map>       // for std::map
#include <memory>    // for std::shared_ptr

....

std::map<C1, std::shared_ptr<Data>> map1;
std::map<C2, std::shared_ptr<Data>> map2;
std::list<Data> values;
std::map<C1, std::list<Data>::iterator> byC1;
std::map<C2, std::list<Data>::iterator> byC2;
struct MyPoint
{
    std::pair<int, int> cartesianPoint;
    std::pair<int, int> radianPoint;

    bool operator== (const MyPoint& rhs)
    {
         if (cartesianPoint == rhs.cartesianPoint || radianPoint == rhs.radianPoint)
             return true;
         return false;
    }
}
std::unordered_map<MyPoint, DataType> myMultIndexMap;