代码之家  ›  专栏  ›  技术社区  ›  Fire Lancer

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

  •  3
  • Fire Lancer  · 技术社区  · 15 年前

    我有一大堆东西(可能有1000个)需要放在一个容器里。我需要能够以两种方式找到特定的实例,一种是通过ID号(64bit unsigned int),另一种是通过名称(std::string)。通常按ID是最常见的,但是在某些情况下,名称是已知的,而不是ID。

    std::map可以提供一个单独的<->值,但是我不确定是否有两组std::map容器,一个用于id,另一个用于字符串是最好的方法。

    编辑-修订代码和错误:

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

    测试代码:

    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;
    

    你的平均提升模板错误…

    C:\Lb\c++Boo\Boox\AligNeDyStury.HPP(69):错误C28 72:“细节”:歧义符号
    可能是“boost::detail”
    或“boost::multi_index::detail”
    C:\Lb\\Boo\Boox\BulthObjult\Dealth\DexxNoDeBase.HPP(42):参见引用类模板实例化“Boo::AligNeDyStand”正在编译
    具有
    [
    SiZe=4,
    对齐方式=4
    ]
    C:\Lb\\Boo\Boox\BulthObjult\Dealth\DexxNoDeBase.HPP(47):参见类模板实例化的引用:Booo::Mulk索引::细节:PoDyValueSyHORKER被编译
    具有
    [
    值=MyClass *
    ]
    C:\Lb\\Boo\Boox\BoosixObjult\Deave\OrdRealXix.No.HPP(582):参见引用类模板实例化“Booo::MultIQue::Debug::索引xNoDeBaseBASE”正在编译
    具有
    [
    值=myClass*,
    分配器=std::分配器
    ]
    C:\Lb\\Boo\Boox\Boox\MulthObjultOrdEdEdEngult.HPP(137):参见引用“类模板实例化”:Boo::MultOxEng:::Orth::OrrordEdPixxLoad节点正在编译
    具有
    [
    super=boost::multi_index::detail::index_node_base>
    ]
    C:\Lb\\Boo\Boox\Boox\MulthObjultOrdEdEdEngult.HPP(119):参见引用“类模板实例化”:Boo::MultOxEng:::Orth::OrrordEdType索引正在编译
    具有
    [
    keyfrmValue=boost::multi_index::const_mem_fun,
    比较=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_标记
    ]
    C:\Lb\\Boo\Boox\Boox\MulyIdIXX.Pult.HPP(86):参见引用“类模板实例化”Boo::MulnOxEng:::Orth::OrrordEdType索引正在编译
    具有
    [
    keyfrmValue=boost::multi_index::const_mem_fun,
    比较=标准::更少,
    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_标记
    ]
    C:\projects\bad\u angle\u studios\brak3\trunk\source\source\server\myclass.cpp(18):请参见正在编译的类模板实例化“boost::multi-index::multi-index\u container”
    具有
    [
    值=myClass*,
    indexSpecifierList=boost::multi_index::indexed_by>,boost::multi_index::ordered_unique>gt;
    ]
    C:\Lb\c++Boo\Boox\AligNeDyStury.HPP(53):错误C28 72:“细节”:歧义符号
    可能是“boost::detail”
    或“boost::multi_index::detail”
    C:\Lab\C++Boo\Boox\AligNeDySturial.HPP(56):参见类模板实例化“Boosi::详细信息::AligNeDyStimult::AlgNeNdE-StulaGigIMP::DATAYT”正在编译
    具有
    [
    SiZe=4,
    对齐方式=4
    ]
    C:\Lb\C++Boo\Boox\AligNeDySturial.HPP(69):参见类模板实例化“Boosi::详细信息::AligndIsStult::AligndIsSturaGuig IMP”正在编译
    具有
    [
    尺寸=4,
    对齐方式=4
    ]
    C:\Lb\c++Boo\Boox\AligNeDyStury.HPP(73):错误C28 72:“细节”:歧义符号
    可能是“boost::detail”
    或“boost::multi_index::detail”
    C:\projects\bad\u angle\u studios\brak3\trunk\source\source\server\myclass.cpp(44):错误C2676:二进制“[”:“myclasslist”未定义此运算符或转换为预定义运算符可接受的类型

    5 回复  |  直到 15 年前
        1
  •  5
  •   Benoît photo_tom    15 年前

    多索引是解决问题的方法。见 there 有关如何使用它的详细信息。

        2
  •  1
  •   Harald Scheirich    15 年前

    这里还有另一个替代方法,您选择哪种解决方案取决于您的需要。抓取sqllite将关于对象的数据存储在数据库中,并为它们运行查询。

        3
  •  1
  •   Joaquín M López Muñoz    15 年前

    火枪,你不符合boost.multiindex名称的条件,而不是例如 boost::indexed_by 你得写信 boost::multi_index::indexed_by 等等。

        4
  •  0
  •   Anna    15 年前

    两个映射(一个以id为键,另一个以name为键)的方法对我来说似乎很好。它很容易实现,而且会很好地工作。

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

        5
  •  -1
  •   Glen    15 年前

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

    find算法比std::map和std::set的find方法慢,所以如果性能是一个大问题,那么在速度上最好不要使用交易空间,或者使用2个map,或者使用boost。

    编辑, 只是想了一下。将数据存储在地图中,使用ID作为键,因为这是常见的情况。然后使用std::find算法和一个与不常见情况的名称匹配的谓词。这样可以减少(但不能消除)性能问题