具有多个键类型的关联数组,可能吗?

发布于 2024-08-15 13:49:47 字数 4690 浏览 2 评论 0原文

我有一大堆对象(可能有 1000 个),我需要将它们存储在容器中。我需要能够通过两种方式找到特定实例,要么通过其 ID 号(64 位无符号整数),要么通过其名称(std::string)。一般来说,最常见的是通过 ID,但在某些情况下,名称已知,但 ID 未知。

std::map 可以提供单个 <->值,但是我不确定拥有 2 组 std::map 容器(一组用于 Id,另一组用于字符串)是否是这里的最佳方法。

编辑-修订的代码和错误:

好吧,我想我应该尝试一下多重索引,因为无论如何我都有提升,但是我似乎无法编译它,即使我已经完成了与中完全相同的操作据我所知,文档:(

测试代码:

namespace common
{
    class MyBaseClass
    {
    public:
        typedef boost::uint64_t Id;

        //name and id are constant, at least for the period im intrested in
        //when I want it in the container...
        const std::string &getName()const{return name;}
        Id getId()const{return id;}

        ...other stuff...
    };
}

class MyClass : public common::MyBaseClass
{
    ...other stuff...
};

typedef boost::multi_index_container
<
    MyClass*,
    boost::indexed_by
    <
        boost::ordered_unique<boost::const_mem_fun<MyBaseClass, MyBaseClass::Id,    &MyBaseClass::getId  > >,
        boost::ordered_unique<boost::const_mem_fun<MyBaseClass, const std::string&, &MyBaseClass::getName> >
    >
>MyClassList;

以及你的平均boost模板错误......

c:\lib\c++\boost\boost\aligned_storage.hpp(69):错误 C2872:“详细信息”:不明确的符号
可能是“boost::detail”
或“boost::multi_index::detail”
c:\lib\c++\boost\boost\multi_index\detail\index_node_base.hpp(42) :请参阅正在编译的类模板实例化“boost::aligned_storage”的参考

[
大小_=4,
对齐_=4
]
c:\lib\c++\boost\boost\multi_index\detail\index_node_base.hpp(47) :请参阅正在编译的类模板实例化 'boost::multi_index::detail::pod_value_holder' 的参考

[
值=我的类*
]
c:\lib\c++\boost\boost\multi_index\detail\ord_index_node.hpp(582) :请参阅正在编译的类模板实例化 'boost::multi_index::detail::index_node_base' 的参考

[
值=MyClass *,
分配器=std::分配器
]
c:\lib\c++\boost\boost\multi_index\ordered_index.hpp(137) :请参阅正在编译的类模板实例化“boost::multi_index::detail::ordered_index_node”的参考

[
超级=boost::multi_index::detail::index_node_base>
]
c:\lib\c++\boost\boost\multi_index\ordered_index.hpp(119) :请参阅正在编译的类模板实例化 'boost::multi_index::detail::ordered_index' 的参考

[
KeyFromValue=boost::multi_index::const_mem_fun,
比较=std::less,std::分配器>>,
SuperMeta=boost::multi_index::detail::nth_layer<2,MyClass *,boost::multi_index::indexed_by>,boost::multi_index::ordered_unique>>,std::allocator>,
TagList=boost::mpl::vector0,
类别=boost::multi_index::detail::ordered_unique_tag
]
c:\lib\c++\boost\boost\multi_index_container.hpp(86) :请参阅正在编译的类模板实例化 'boost::multi_index::detail::ordered_index' 的参考

[
KeyFromValue=boost::multi_index::const_mem_fun,
比较=std::less,
SuperMeta=boost::multi_index::detail::nth_layer<1,MyClass *,boost::multi_index::indexed_by>,boost::multi_index::ordered_unique>>,std::allocator>,
TagList=boost::mpl::vector0,
类别=boost::multi_index::detail::ordered_unique_tag
]
c:\projects\bad_angle_studios\brak3\trunk\source\source\server\MyClass.cpp(18) :参见正在编译的类模板实例化 'boost::multi_index::multi_index_container' 的参考

[
值=MyClass *,
IndexSpecifierList=boost::multi_index::indexed_by>,boost::multi_index::ordered_unique>>
]
c:\lib\c++\boost\boost\aligned_storage.hpp(53):错误 C2872:“详细信息”:不明确的符号
可能是“boost::detail”
或“boost::multi_index::detail”
c:\lib\c++\boost\boost\aligned_storage.hpp(56) :请参阅正在编译的类模板实例化 'boost::detail::aligned_storage::aligned_storage_imp::data_t' 的参考

[
大小_=4,
对齐_=4
]
c:\lib\c++\boost\boost\aligned_storage.hpp(69) :请参阅正在编译的类模板实例化“boost::detail::aligned_storage::aligned_storage_imp”的参考

[
大小_=4,
对齐_=4
]
c:\lib\c++\boost\boost\aligned_storage.hpp(73):错误 C2872:“详细信息”:不明确的符号
可能是“boost::detail”
或“boost::multi_index::detail”
c:\projects\bad_angle_studios\brak3\trunk\source\source\server\MyClass.cpp(44) : 错误 C2676: 二进制 '[' : 'MyClassList' 未定义此运算符或转换为预定义可接受的类型运算符

Ive got a large bunch of objects (potentially 1000's) which I need to store in a container. I need to be able to find specific instances in two ways, either by its ID number (64bit unsigned int), or its name (std::string). Generally by ID will be the most common, however in some cases the name is known, but not the ID.

std::map can provide a single <-> value, however I'm not sure if having 2 sets of std::map containers, one for the Ids and another for the strings is the best approach here.

EDIT - REVISED code and error:

Ok, I figured i'd give the multi index a try since I have boost anyways, however I can't seem to get it to compile even though I've done it exactly the same as in the documentation as far as I can tell :(

test code:

namespace common
{
    class MyBaseClass
    {
    public:
        typedef boost::uint64_t Id;

        //name and id are constant, at least for the period im intrested in
        //when I want it in the container...
        const std::string &getName()const{return name;}
        Id getId()const{return id;}

        ...other stuff...
    };
}

class MyClass : public common::MyBaseClass
{
    ...other stuff...
};

typedef boost::multi_index_container
<
    MyClass*,
    boost::indexed_by
    <
        boost::ordered_unique<boost::const_mem_fun<MyBaseClass, MyBaseClass::Id,    &MyBaseClass::getId  > >,
        boost::ordered_unique<boost::const_mem_fun<MyBaseClass, const std::string&, &MyBaseClass::getName> >
    >
>MyClassList;

and your average boost template error...

c:\lib\c++\boost\boost\aligned_storage.hpp(69) : error C2872: 'detail' : ambiguous symbol
could be 'boost::detail'
or 'boost::multi_index::detail'
c:\lib\c++\boost\boost\multi_index\detail\index_node_base.hpp(42) : see reference to class template instantiation 'boost::aligned_storage' being compiled
with
[
size_=4,
alignment_=4
]
c:\lib\c++\boost\boost\multi_index\detail\index_node_base.hpp(47) : see reference to class template instantiation 'boost::multi_index::detail::pod_value_holder' being compiled
with
[
Value=MyClass *
]
c:\lib\c++\boost\boost\multi_index\detail\ord_index_node.hpp(582) : see reference to class template instantiation 'boost::multi_index::detail::index_node_base' being compiled
with
[
Value=MyClass *,
Allocator=std::allocator
]
c:\lib\c++\boost\boost\multi_index\ordered_index.hpp(137) : see reference to class template instantiation 'boost::multi_index::detail::ordered_index_node' being compiled
with
[
Super=boost::multi_index::detail::index_node_base>
]
c:\lib\c++\boost\boost\multi_index\ordered_index.hpp(119) : see reference to class template instantiation 'boost::multi_index::detail::ordered_index' being compiled
with
[
KeyFromValue=boost::multi_index::const_mem_fun,
Compare=std::less,std::allocator>>,
SuperMeta=boost::multi_index::detail::nth_layer<2,MyClass *,boost::multi_index::indexed_by>,boost::multi_index::ordered_unique>>,std::allocator>,
TagList=boost::mpl::vector0,
Category=boost::multi_index::detail::ordered_unique_tag
]
c:\lib\c++\boost\boost\multi_index_container.hpp(86) : see reference to class template instantiation 'boost::multi_index::detail::ordered_index' being compiled
with
[
KeyFromValue=boost::multi_index::const_mem_fun,
Compare=std::less,
SuperMeta=boost::multi_index::detail::nth_layer<1,MyClass *,boost::multi_index::indexed_by>,boost::multi_index::ordered_unique>>,std::allocator>,
TagList=boost::mpl::vector0,
Category=boost::multi_index::detail::ordered_unique_tag
]
c:\projects\bad_angle_studios\brak3\trunk\source\source\server\MyClass.cpp(18) : see reference to class template instantiation 'boost::multi_index::multi_index_container' being compiled
with
[
Value=MyClass *,
IndexSpecifierList=boost::multi_index::indexed_by>,boost::multi_index::ordered_unique>>
]
c:\lib\c++\boost\boost\aligned_storage.hpp(53) : error C2872: 'detail' : ambiguous symbol
could be 'boost::detail'
or 'boost::multi_index::detail'
c:\lib\c++\boost\boost\aligned_storage.hpp(56) : see reference to class template instantiation 'boost::detail::aligned_storage::aligned_storage_imp::data_t' being compiled
with
[
size_=4,
alignment_=4
]
c:\lib\c++\boost\boost\aligned_storage.hpp(69) : see reference to class template instantiation 'boost::detail::aligned_storage::aligned_storage_imp' being compiled
with
[
size_=4,
alignment_=4
]
c:\lib\c++\boost\boost\aligned_storage.hpp(73) : error C2872: 'detail' : ambiguous symbol
could be 'boost::detail'
or 'boost::multi_index::detail'
c:\projects\bad_angle_studios\brak3\trunk\source\source\server\MyClass.cpp(44) : error C2676: binary '[' : 'MyClassList' does not define this operator or a conversion to a type acceptable to the predefined operator

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

夜司空 2024-08-22 13:49:47

boost::multi_index 是您问题的答案。请参阅那里了解更多信息关于如何使用它。

boost::multi_index is the answer to your problem. See there for more information on how to use it.

阳光的暖冬 2024-08-22 13:49:47

这是上述方案的另一种替代方案,您选择哪种解决方案取决于您的需求。 Grab SqlLite 将有关对象的数据存储在数据库中并对其运行查询。

Here is another alternative to the above, which solution you pick depends on your needs. Grab SqlLite store the data about your objects in a database and run queries for them.

七色彩虹 2024-08-22 13:49:47

Fire Lancer,您没有正确限定 Boost.MultiIndex 名称,而不是例如 boost::indexed_by 您必须编写 boost::multi_index::indexed_by,等等。

Fire Lancer, you're not qualifying Boost.MultiIndex names correctly, instead of for instance boost::indexed_by you've got to write boost::multi_index::indexed_by, etcetera.

我不吻晚风 2024-08-22 13:49:47

两张地图的方法(一张以 ID 作为键,第二张以名称作为键)对我来说似乎很好。它实施起来很简单,并且效果很好。

我看到其他答案推荐了 boost 库。如果您已经在项目中使用了 boost,那么它可能是一个很好的解决方案。如果你不这样做 - 我不确定是否值得仅仅为了这个简单的情况而为你的项目添加提升。

The approach of two maps (one with ID as key, and the second with name as key), seems good to me. It is simple to implement, and will work well.

I saw that other answers recommended boost libraries. If you already use boost in your project, then it could be a good solution. If you don't - I'm not sure it is worth adding boost to your project just for this simple case.

你爱我像她 2024-08-22 13:49:47

您可以将数据存储在 std::vector 中,并使用 std::find 算法来查找您的项目。查找算法接受不同的比较器,因此只需定义一个与 id 匹配的比较器和另一个与名称匹配的比较器。

查找算法比 std::map 和 std::set 的查找方法慢,因此如果性能是一个大问题,那么您最好用空间换取速度,使用 2 个映射或使用 boost

edit,< /b> 只是有一个想法。使用 id 作为键将数据存储在地图中,因为这是常见情况。然后使用 std::find 算法和与不常见情况的名称匹配的谓词。这应该会减少(但不能消除)性能问题

You could store the data in a std::vector and use the std::find algorithm to find your items. The find algorithm accepts different comparators, so just define one that matches ids and another that matches names.

The find algorithm is slower than std::map and std::set's find method, so if performance is a big concern then you're probably better off trading space for speed and either using 2 maps or using boost

edit, just had a thought. Store the data in a map, using the id as a key, as this is the common case. Then use the std::find algorithm and a predicate that matches on name for the uncommon case. That should reduce (but not remove)the performance issues

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文