1

I currently have two maps that link enum values to strings, one direction to convert file input to internal representation, the other to print (debug) information about that internal representation. I would like to change the map to a vector for generally faster access and conversion. But then this function, which works as it should, won't work:

template<class T, class Y>
const T & map_value( const std::map<Y,T> &map, const Y &key )
{
    return (*map.find(key)).second;
}

So I tried to make it into this:

template<class Cont, class T, class Y>
const T & map_value( const Cont &map, const Y &key )
{
    return map[key];
}

But then I get no matching function call. I have just had an epiphany writing this question; const map has no member operator[], which makes this a hard thing to do. How should I write map_value so it works as fast as possible for both vector and map?

8
  • how is Cont declared/defined? Commented Jun 8, 2011 at 16:30
  • The template is instantiated with Cont being a const std::map<some_enum_class, std::string> or the inverse map. I'd like to change the inverse map to a std::vector<std::string> and convert the enum class values to index values. Commented Jun 8, 2011 at 16:35
  • I suggest using map.find() rather than map[], the former does not insert new key, value pairs. Commented Jun 8, 2011 at 16:40
  • @Thomas: but that would be slow for vector, where operator[] is faster. Commented Jun 8, 2011 at 16:40
  • @rubenvb: You can choose to spend the time converting the text into a numeric index for the vector or let the std::map compare and dive down the binary tree. I vote for the method that is simplest, easiest to read and understand over something more complicated that would produce negligible time savings. Commented Jun 8, 2011 at 16:48

2 Answers 2

2

Leave the first definition as it is, but change the second one to cover all vectors. Use both in your program, the compiler will choose the appropriate version as necessary.

template<class T, class Y>
const T & map_value( const std::map<Y,T> &map, const Y &key )
{
    return (*map.find(key)).second;
}

template<class T>
const T & map_value( const std::vector<T> &map, size_t key )
{
    return map[key];
} 
Sign up to request clarification or add additional context in comments.

Comments

2

This is a one-liner. Surely overloading it for both types (maps and vectors) isn’t too much overhead.

In fact, this is the only way to do this. I understand the desire to have a function that’s as general as possible – good! – but you need to encapsulate the respective access mode (find vs. operator []). And in your case the function does nothing but accessing the data structure.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.