开发者

Adding elements to an STL Map in a constructors Initialization List?

开发者 https://www.devze.com 2022-12-10 17:27 出处:网络
I was wondering if this was possible, and if so how I\'d go about doing so.If 开发者_StackOverflowit\'s not possible I\'ll just have to add the elements during the constructor body.

I was wondering if this was possible, and if so how I'd go about doing so. If 开发者_StackOverflowit'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.


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


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.


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.


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!

0

精彩评论

暂无评论...
验证码 换一张
取 消