3

I know that it is a bad idea to inherit from stl classes. But is there any other way to extend them?

Let's say that to improve readability, I wanted to be able to call an "add" method on my vectors instead of the less readable "push_back".

Or perhaps I want to add a simple hasKey method to my std::map.

Is there any way that I could do that, aside from creating an entire wrapper class with a std::vector as a member, passing each function call from my wrapper to the vector?

hmjd
  • 120,187
  • 20
  • 207
  • 252
PortMan
  • 4,205
  • 9
  • 35
  • 61
  • 4
    *'instead of the less readable "push_back"."* .... what? – Pubby Jun 04 '13 at 21:08
  • 1
    myVector.add(myThing) is, in my opinion, easier to quickly read than myVector.push_back(myThing). – PortMan Jun 04 '13 at 21:12
  • 3
    Every C++ programmer should know `std::vector::push_back` while they would need to learn what `add` does. But let's pretend it is just a (bad) example. – Benjamin Bannier Jun 04 '13 at 21:14
  • Where does `add` put the item? What are you going to name `push_front`? How about `insert`? – Edward Strange Jun 04 '13 at 21:18
  • @CrazyEddie: This has tons of issues. I would naively assume `add` to be some 90s `operator+` – Benjamin Bannier Jun 04 '13 at 21:18
  • 3
    It's not a question of knowing what it does. It's a question of readability. Another example would be using `myMap.hasKey(key)` instead of `myMap.find( key ) != myMap.end()` That one is clearly easier to quickly grok. – PortMan Jun 04 '13 at 21:19
  • 3
    @user1916754: This is a horrible example. Every C++ programmers knows the standard library and so should you. Do you also `#define begin {` and `#define end }`? – Benjamin Bannier Jun 04 '13 at 21:24
  • @user - but `find` does something totally different than I'd expect from `hasKey`. The authors of `map` (and the associative container concept in general) did a good thing by not polluting the interface with every conceivable operation. Discovering whether a key is in the map is as easy as you show and would require a `find` anyway even if it was implemented in `map` itself. You have much to learn about software design and maintenance. – Edward Strange Jun 05 '13 at 17:10
  • One should always define better names where possible. Any competent C++ programmer can easily check what it's defined as — this is a core skill in reading C++ headers, where typedefs are one of the favourite tricks. However, instead of `hasKey(..)`, one would simply use `!myMap.count(key)`, which does the same, so the STL is only slightly less readable than would be perfect. – Evgeni Sergeev Jul 05 '15 at 14:19

2 Answers2

14

You should use free functions:

template<typename... Args>
bool has_key(std::map<Args...> const& map, typename std::map<Args...>::key_type key) {
  return map.find(key) != map.end();
}

Don't use inheritance if it's not necesarry. That's silly.

Pubby
  • 51,882
  • 13
  • 139
  • 180
3

Once developers become accustomed to the STL names of things, having changed them will make the code less maintainable. This is generally a bad idea. In practice, since STL classes don't provide a virtual destructor, it's not possible to inherit from them and have good destruction behavior.

Joel
  • 5,618
  • 1
  • 20
  • 19