tags:

views:

49

answers:

2

My goal is to store all the keys of a map (first item) to a vector and I'm doing the following.

    template < class vecDet>
class storeInto
{
 public:
  storeInto(vecDet& source) : VectorInfo(source) { }
  ~storeInto();
  template <class pairdet>
  void operator()(pairdet& pairinfo) 
  {
   VectorInfo.push_back(pairinfo.first);
  }

 private:
  vecDet& VectorInfo;
};
template<class mapDet, class vecDet>
void storeMapToVector(const mapDet& mapContA,  vecDet& vecContA)
{
 for_each(mapContA.begin(), mapContA.end() , storeInto<vecDet>(vecContA));
}

Finally, from my main program, I'm calling the storeMapToVector() as follows

storeMapToVector<mapinfo,vector<char> >(mapContents, vecContents);

where mapinfo is declared as follows

typedef map<char,int> mapinfo;

Is there a better way to do this? Is there anything wrong with this?

A: 

The code seems fine. Some nitpicks though:

~storeInto();

What do you need the destructor for? The functor could just live without it.

storeMapToVector<mapinfo,vector<char> >(mapContents, vecContents);

The template argument list seems unnecessary here, it could just be

storeMapToVector(mapContents, vecContents);

The template parameters would be inferred in this context.

jpalecek
Thanks a lot guys.
+3  A: 

Your code looks like it would work at first glance. However, there's a much simpler way to do this:

I haven't evaluated your code, but there is certainly a much easier way to do what you want built into most STL implementations:

vecContents.resize(mapContents.size());
std::transform(mapContents.begin(), mapContents.end(), vecContents.begin(),
    select1st<pair<const char, int> >());

Alternatively:

vecContents.resize(mapContents.size());
std::transform(mapContents.begin(), mapContents.end(), vecContents.begin(),
    select1st<mapinfo::value_type>());

There is 1 wrinkle though - select1st is a SGI extension. It's in almost every STL implementation but where varies. For GNU, you have to do:

#include <ext/functional>

using __gnu_cxx::select1st; // or just using namespace __gnu_cxx;

See this answer for using it in Visual Studio.

Walter Mundt
select1st is technically an SGI extension so, depending on your STL implementation, you may need to do some extra work to get it to compile.
Eugen Constantin Dinca
Good catch! Answer edited with information on that.
Walter Mundt