我有两个c ++程序需要有一个映射type -> int
,它在编译时是已知的,在两个程序之间是相同的。此外,我想在编译时自动确保地图是一对一的。你会如何解决这个问题? (允许使用c ++ 0x扩展名)。第一部分很简单:分享
template < typename T > struct map;
template <> struct map <...> { enum { val = ...; }; };
程序之间。 (第二部分意味着我不想在程序中的某个地方为两种不同的类型意外定义相同的val
。)
答案 0 :(得分:9)
确保唯一ID的一种方法是滥用朋友的功能定义
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> { };
答案 1 :(得分:3)
如何使用boost::mpl::map?分享类似:
// Include your headers
using namespace boost::mpl;
typedef map<
pair<1,MyFirstClass>
, pair<2,MySecondClass>
, pair<3,MyThirdClass>
> m;
答案 2 :(得分:1)
他们在编译时没有严格,但这对函数会自动为传递给它们的每种类型生成一个唯一的ID:
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
它们之间,并至少避免代码重复。这也免除了你自己为每种类型提出唯一ID的问题,正如Johannes Schaub的回答所做的那样,尽管他的优点是在编译时完全完成并因此由编译器进行静态检查。我只提供另一种选择。
答案 3 :(得分:0)
一种简单的方法可能是在两个程序中共享同一个类。
重复使用是OOP的目标之一。
可以创建封装映射及其初始化的类,然后在两个C ++程序中使用。