-2

I have a class that stores two maps like so:

class Database {
    std::map<A,B> map1;
    std::map<C,A> map2;
};

I have just included part of the class. Database has more functions and data elements that I have not included.

I want to change the implementation of map from std::map to something else that has the same public interface. This seems to be a good place for templating.

Normally, I would write template<class Map> at the top and be done. However, there are a problem.

Map is not specialized within this class. For example, if I just need a Map. Writing template would be fine. I would define 'Database' as Database<std::map<A, B>>. However, I need two separate map instances.

Do I need to write template<class Map1, class Map2> and define 'Database' as Database<std::map<A, B>>? Or is there a better way of doing the templated definition. Or are templates the wrong technique for this situation?

Ideally, I would like to be able to write Database<std::map>. Is this possible?

I had previously checked:

Error when pass std::map as template template argument

Error passing map to template function in C++

Passing unspecialized template as a template parameter

However, these two not really deal with my problem of having two different parameterizations.

EDIT: Overall, I am trying to specify the implementation of map for Database. I want to be able to write Database or Database and have the map elements of Database be implemented in the specified way.

Community
  • 1
  • 1
Halbort
  • 742
  • 1
  • 6
  • 19
  • Why was I downvoted? – Halbort Oct 31 '16 at 00:45
  • What are you *trying* to do here? You're talking a lot about possible solutions, but not about your problem. – tadman Oct 31 '16 at 01:07
  • I am trying to specify the implementation of map for Database. I want to be able to write Database or Database and have the map elements of Database be implemented in the specified way. – Halbort Oct 31 '16 at 01:12
  • I'm not sure you're tackling this problem the right way. Templates are trouble. Why not have a base class of some kind with a well-defined interface, then store that as a pointer so you can pass in an arbitrary subclass. – tadman Oct 31 '16 at 01:24
  • I considered that. However, http://stackoverflow.com/questions/20829860/what-is-the-c-equivalent-of-inheriting-a-java-collection-interface-set-map?rq=1 seemed to indicate that templates were a more idiomatic solution. – Halbort Oct 31 '16 at 01:28
  • That depends on what object-oriented design school of thinking you're using. C++ templates *can* be powerful, but if they're the only tool you ever use they can easily be abused. – tadman Oct 31 '16 at 01:30
  • However, std::map does not have any interface that I know of. So I do not think I can make pass an interface pointer. – Halbort Oct 31 '16 at 01:31
  • I'm talking about making an abstract base class that implements an interface like `std::map`. – tadman Oct 31 '16 at 01:48
  • I understand that. But how would I pass std::map to Database if it has no connection to the abstract base class. Moreover, I would have to pass two pointers one for each map, which is not an improvement over just passing two templated types. – Halbort Oct 31 '16 at 01:54
  • It's an improvement if you can get it working within the limitations of C++. You really need to try and make this happen. Your question here is missing some experimentation. – tadman Oct 31 '16 at 02:01

1 Answers1

1

You may be looking for template template parameters. Something like this:

template <template <class...> class Map>
class Database {
    Map<A, B> map1;
    Map<C, A> map2;
};

Database<std::map> dbOnStdMap;

Demo

Igor Tandetnik
  • 50,461
  • 4
  • 56
  • 85