type to int mapping

I have two c++ programs that need to have a map type -> int that is known at compile time and equal between the two programs. Furthermore, I'd like to automatically make sure at compile time that the map is one-to-one. How would you solve that? (c++0x-extensions are allowed). The first part is easy: Share a

template < typename T > struct map;
template <> struct map <...> { enum { val = ...; }; };

between the programs. (The second part means that I don't want to accidently define the same val for two different types somewhere in my programs.)

Answers


One way to ensure uniqe ids is to abuse friend function definitions

template<int N>
struct marker_id {
  static int const value = N;
};

template<typename T>
struct marker_type { typedef T type; };

template<typename T, int N>
struct register_id : marker_id<N>, marker_type<T> {
private:
  friend marker_type<T> marked_id(marker_id<N>) {
    return marker_type<T>();
  }
};

template<typename T>
struct map;

template<>
struct map<int> : register_id<int, 0> { };

// The following results in the following GCC error
// x.cpp: In instantiation of 'register_id<float, 0>':
// x.cpp:26:43:   instantiated from here
// x.cpp:14:29: error: new declaration 'marker_type<float> marked_id(marker_id<0>)'
// x.cpp:14:29: error: ambiguates old declaration 'marker_type<int> marked_id(marker_id<0>)'
//
//// template<>
//// struct map<float> : register_id<float, 0> { };

How about using boost::mpl::map? Share something like:

// Include your headers

using namespace boost::mpl;
typedef map<
      pair<1,MyFirstClass>
    , pair<2,MySecondClass>
    , pair<3,MyThirdClass>
    > m;

They don't do it strictly at compile time, but this pair of functions will automatically generate a unique ID for each type passed to them:

template<class T>
int generate_type_id() {

    static int value = 0;
    return value++;

}

template<class T>
int type_id() {

    static int value = generate_type_id<T>();
    return value;

}

And you should be able to ensure that the two applications share the same identifiers for a given type by explicitly invoking the functions in order in both projects:

type_id<int>();
type_id<Foo>();
type_id< map<string, pair<int, Bar> >();

Yes, this forces you to write a list of all involved types, but you can toss it in a header, #include it between them, and at least avoid code duplication. This also absolves you of having to come up with unique IDs for each type on your own, as Johannes Schaub's answer does, though his has the advantage of being done completely at compile-time and thus statically checked by the compiler. I'm only offering an alternative.


An easy approach might be to just share the same class in both programs.

Re-use is one of the objectives to OOP.

A class that encapsulates the map and its initialization can be created and then used in both C++ programs.


Need Your Help

Angular 2 change detection within *ngFor seems not to work (RC5)

angular ngfor angular2-changedetection

Within my ng2 module a function is called by another module to create an object and push it to an array which is bound to *ngFor in the template. According to the docs https://angular.io/docs/ts/la...

How to insert PHP code into WordPress Custom Fields

php wordpress field

I'm trying to figure out how to put PHP code into a custom field, but so far all that happens is that it displays the code literally, instead of executing it. So, how would I go about getting the P...