Thursday, March 31, 2011

What's the simplest way to create an STL - identity map?

I'd like to initialize a map - object "id" with identities from 0 to n-1, i.e.

 id[0] = 0
 id[1] = 1
 .
 .
 id[n-1] = n-1

Is there a simple way - a one-liner, a method inside the map-object, simply something really simple - that does that?

From stackoverflow
  • You could use the

    template <class InputIterator>
    map(InputIterator f, InputIterator l,
        const key_compare& comp)
    

    form of the constructor, but you'd need to build an InputIterator that worked as a generator function over the range you want. That'd be a whole lot more typing than just using a for loop.

  • What is wrong with

    for(unsigned int i = 0; i < n; ++i)
        id[i] = i;
    
    secr : I was expecting that STL offers a method that facilitates this loop.
    jheriko : I find STL will make some simple tasks into more (characters or lines of) code. This is because of the way it is designed, e.g. using iterator classes instead of ints, to allow more general purpose iteration. Personally I avoid STL for simple tasks, vanilla code is often quicker and easier to debug.
    Crashworks : Any STL builtin will just resolve to this loop under the hood, except with a whole bunch more keystrokes.
  • It seems a little weird to use a map with the key being a simple index. Are you sure you cannot use a vector? Doing so, you could use boost::counting_iterator to fill the vector:

    std::vector<int> v(boost::counting_iterator<int>(0), 
                       boost::counting_iterator<int>(N-1));
    // v is filled with integers from 0 to N-1
    

    However, I'm not sure whether this is a huge gain compared to the simple for loop.

  • Look out for std::iota as part of the numeric library (C++0x feature):

    template <ForwardIterator Iter, HasPreincrement T>
    requires OutputIterator<Iter, const T&>
    void iota(Iter first, Iter last, T value);
    

0 comments:

Post a Comment