тип для отображения int - PullRequest
       27

тип для отображения int

5 голосов
/ 18 сентября 2010

У меня есть две программы на c ++, которым требуется карта type -> int, известная во время компиляции и равная между двумя программами. Кроме того, я хотел бы автоматически убедиться во время компиляции, что карта один-к-одному. Как бы вы решили это? (разрешены c ++ 0x-расширения). Первая часть проста: Поделиться

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

между программами. (Вторая часть означает, что я не хочу случайно определять один и тот же val для двух разных типов где-то в моих программах.)

Ответы [ 4 ]

9 голосов
/ 18 сентября 2010

Один из способов обеспечения уникальности идентификаторов - злоупотребление определениями функций друзей

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> { };
3 голосов
/ 18 сентября 2010

Как насчет использования boost :: mpl :: map ? Поделитесь чем-то вроде:

// Include your headers

using namespace boost::mpl;
typedef map<
      pair<1,MyFirstClass>
    , pair<2,MySecondClass>
    , pair<3,MyThirdClass>
    > m;
1 голос
/ 18 сентября 2010

Они не делают этого строго во время компиляции, но эта пара функций автоматически сгенерирует уникальный идентификатор для каждого переданного им типа:

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;

}

И вы должны быть в состоянии гарантировать, что два приложения совместно используют одинаковые идентификаторы для данного типа, явно вызывая функции по порядку в обоих проектах:

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

Да, это заставляет вас писать список всех задействованных типов, но вы можете добавить его в заголовок, #include между ними, и, по крайней мере, избежать дублирования кода. Это также освобождает вас от необходимости придумывать уникальные идентификаторы для каждого типа самостоятельно, как отвечает ответ Йоханнеса Шауба, хотя его преимущество заключается в том, что он выполняется полностью во время компиляции и, таким образом, статически проверяется компилятором. Я только предлагаю альтернативу.

0 голосов
/ 18 сентября 2010

Простой подход может заключаться в том, чтобы просто использовать один и тот же класс в обеих программах.

Повторное использование является одной из целей ООП.

Класс, который инкапсулирует карту и ее инициализацию, может быть создан и затем использован в обеих программах на C ++.

...