Adding elements to an STL Map in a constructors In

2019-04-02 11:21发布

问题:

I was wondering if this was possible, and if so how I'd go about doing so. If it's not possible I'll just have to add the elements during the constructor body.

Ideally I would like the map immutable after construction.

What I'm trying to achieve is adding two pairs to the map that are created from constructor parameters.

回答1:

It's possible, by copy construction: invoke a function which build the map!

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;
};


回答2:

Without extra tools you can only init std containers in initialization lists as far as their constructors support you. If you need more, map_list_of() et al from Boost.Assign do a great job.

Boost.Assign in action:

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

edit: updated to std::map example.



回答3:

There’s a map constructor that takes a range as a pair of iterators. Using that, you can construct something similar to your demands:

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

Granted, not pretty. The next version of C++ will come with better support for initialization lists. Until then, Boost.Assign is the next best thing.



回答4:

I use an initializer class:

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;
    }
};

Then to put it to use:

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" ) )
    {}
};

This is free (in the sense that you aren't building a map, copying it, and throwing the first away) because of C++'s return value optimization. The same thing can be done for initializing a vector or other standard containers.

Hope that helps!