0

I have a std::map<std::string,foo> and need to frequently find() elements when instead of a std::string, I have a const char*. However, map.find("key_value") won't work, I need a std::string. So, I would need to map.find(std::string{"key_value"}), but this will create a temporary std::string (with its allocation and de-allocation) each time, making this potentially inefficient. Is this reasoning correct? If yes, how can I improve the situation?

I was think about using a wrapper around const char* as key for the map which has its own comparison function and can be cheaply wrapped around any const char*, no need for allocations. Is this a good idea? (note that my mapped values are not copyable, only movable).

Walter
  • 44,150
  • 20
  • 113
  • 196

1 Answers1

1

You can avoid the temporaries by using 0-terminated strings and a custom comparator for the map.
Still, using an unordered_map would likely yield better indexing performance.

An alternative (much better), is using a wrapper, just as you think.
There is actually already std::reference_wrapper for that task.

Still, the first rule of optimisation: Do not do it.
The second rule: Do not do it.
The third rule (only for experts): After measurement and careful consideration, you might do it anyway.

The only downside is: You must manually manage the lifetimes of your strings.

If you are going down that road anyway, and you do not free any string until you free them all, consider using your own custom allocator.

Deduplicator
  • 44,692
  • 7
  • 66
  • 118
  • I know that I can, I said so myself in the question. But is this a good idea? – Walter Apr 25 '14 at 01:23
  • @Walter: Nearly every time, no. Still, you could have that one case where it's worthwhile. – Deduplicator Apr 25 '14 at 01:26
  • This is confusing. According to [this](http://en.cppreference.com/w/cpp/container/map/find), `map.find()` wouldn't allow `const char*` arguments, but both gcc and clang compile fine and it works ?!?! – Walter Apr 25 '14 at 01:42
  • There is an implicit conversion to `std::string` involved. Just let them give you the overloads: Call with unsuitable parameter and decode the error message. – Deduplicator Apr 25 '14 at 01:43
  • Just to keep you updated. I actually did exactly this: defined a wrapper around `const char*`, overloaded all comparison operators and type conversions, and used a custom allocator (allocating chunks of many `char`). Works fine. Alternatively, one may simply supply a custom allocator to `std::string`. – Walter Apr 25 '14 at 23:14