【问题标题】:Adding elements to an STL Map in a constructors Initialization List?在构造函数初始化列表中将元素添加到 STL 映射?
【发布时间】:2009-11-04 15:15:15
【问题描述】:

我想知道这是否可能,如果可以,我将如何去做。如果不可能,我只需要在构造函数主体中添加元素。

理想情况下,我希望地图在构建后不可变。

我想要实现的是将两对从构造函数参数创建的地图添加。

【问题讨论】:

    标签: c++ stl map initialization


    【解决方案1】:

    有可能,通过复制构造:调用构建地图的函数!

    std::map<int,int> myFunc(int a, int b);
    
    class MyObject
    {
    public:
      MyObject(int a, int b): m_map(myFunc(a,b)) {}
    
    private:
      std::map<int,int> m_map;
    };
    

    【讨论】:

    • 这可能相当干净。这是否允许我在初始化时将新构建的映射设为常量?
    • 是的,当然,这意味着赋值运算符将不起作用:)
    • 编译器可能会将副本优化掉并直接在属性中构建它。
    • 很高兴我能提供一个简单的解决方案:)
    • 最佳解决方案,+1。 @Steve:编译器(嗯,所有现代编译器)确实通过在此处省略不必要的副本进行优化。所以这真的很便宜。
    【解决方案2】:

    如果没有额外的工具,你只能在初始化列表中初始化 std 容器,只要它们的构造函数支持你。如果您需要更多,来自 Boost.Assign 的 map_list_of() 等人会做得很好。

    Boost.Assign 实际操作:

    class C
    {
        const std::map<int,int> _vi;
    public:
        C() : _vi(boost::assign::map_list_of(1,1)(2,1)(3,2)) {}
    }
    

    编辑: 更新为std::map 示例。

    【讨论】:

      【解决方案3】:

      有一个 map 构造函数,它将一个范围作为一对迭代器。使用它,您可以构建与您的需求类似的东西:

      pair<int, int> init[] = { make_pair(1, 2), make_pair(2, 3) };
      map<int, int> const mymap(init, init + 2);
      

      当然,不漂亮。 下一版本的 C++ 将对初始化列表提供更好的支持。在那之前,Boost.Assign 是下一个最好的东西。

      【讨论】:

      • 鉴于最后一句话from constructor parameters,我想说你没有抓住重点......就像我第一次尝试时所做的那样。
      • 所以听起来如果我不想在我的初始化块中使用相当复杂的迭代器算术并且没有使用 boost 的选项我被降级到构造函数体?
      • 为了简单起见,我会说在构造函数体中构建你的地图。
      • @Mathieu:当然,这在语法上稍微复杂一些,但它的工作方式基本相同(至少如果这两对是静态可用的,即可以初始化为类的静态成员)。
      【解决方案4】:

      我使用了一个初始化类:

      template<class K, class V>
      class MapInitializer
      {
          std::map<K,V> m;
      public:
          operator std::map<K,V>() const 
          { 
              return m; 
          }
      
          MapInitializer& Add( const K& k, const V& v )
          {
              m[ k ] = v;
              return *this;
          }
      };
      

      然后使用它:

      class C
      {
          const std::map<int,const char*> m_map;
      
      public:        
          C() : m_map( MapInitializer<int,const char*>()
                  .Add( 1, "Hi there" )
                  .Add( 2, "In the middle" )
                  .Add( 9, "Goodbye" ) )
          {}
      };
      

      由于 C++ 的return value optimization,这是免费的(从某种意义上说,您无需构建地图、复制地图并丢弃第一个地图)。初始化向量或其他标准容器也可以这样做。

      希望有帮助!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-07-29
        • 2018-10-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多