2010-09-18 42 views
5

Tôi có hai chương trình C++ cần có một bản đồ type -> int được biết tại thời gian biên dịch và bằng nhau giữa hai chương trình. Hơn nữa, tôi muốn tự động đảm bảo thời gian biên dịch bản đồ là một-một. Làm thế nào bạn sẽ giải quyết được điều đó? (C++ 0x-mở rộng được cho phép). Phần đầu tiên là dễ dàng: Chia sẻ mộtnhập vào ánh xạ int

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

giữa các chương trình. (Phần thứ hai có nghĩa là tôi không muốn vô tình xác định cùng một số val cho hai loại khác nhau ở đâu đó trong các chương trình của tôi.)

+0

Tôi có thể hỏi bản đồ này là để làm gì không? – sellibitze

+0

bản sao có thể có của [Kiểu chuyển đổi siêu lập bản mẫu thành số duy nhất] (http://stackoverflow.com/questions/1708458/template-metaprogram-converting-type-to-unique-number) – kennytm

+0

Bản đồ sẽ được sử dụng để truyền dữ liệu tùy ý giữa người gửi và chương trình người nhận (đó cũng là lý do tại sao câu hỏi này không trùng lặp - nó liên quan đến hai chương trình cần chia sẻ cùng một bản đồ). – Thomas

Trả lời

9

Một cách để đảm bảo id uniqe là lạm dụng các hàm bạn bè các định nghĩa

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> { }; 
+0

Tuyệt! Điều này trông giống như giải pháp hoàn hảo, vì nó giải phóng tôi khỏi việc phải chỉ định tất cả các loại trong danh sách. – Thomas

+1

@Thomas giờ đây nó cũng hiển thị các loại xung đột trong thông báo lỗi. –

2

Làm thế nào để sử dụng boost::mpl::map? Chia sẻ gì đó như:

// Include your headers 

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

Họ không làm điều đó Nghiêm lúc biên dịch, nhưng cặp này các chức năng sẽ tự động tạo một ID duy nhất cho mỗi loại được truyền cho chúng:

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; 

} 

Và bạn sẽ có thể đảm bảo rằng hai ứng dụng chia sẻ t ông cùng một định danh cho một loại nhất định bằng cách gọi một cách rõ ràng hàm theo thứ tự trong cả hai dự án:

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

Vâng, đây buộc bạn phải viết một danh sách tất cả các loại có liên quan, nhưng bạn có thể quăng nó trong một tiêu đề, #include nó giữa chúng và ít nhất là tránh trùng lặp mã. Điều này cũng khiến bạn phải tự mình tạo ra các ID riêng cho từng loại, như câu trả lời của Johannes Schaub, mặc dù anh ta có lợi thế là được thực hiện hoàn toàn tại thời gian biên dịch và do đó được trình biên dịch kiểm tra tĩnh. Tôi chỉ cung cấp một giải pháp thay thế.

+0

Điều này không hoạt động. Khi bạn có 'generate_type_id' templated bởi' T' nó sẽ luôn trả về 0 (http://ideone.com/Ph3ha). Nhưng nếu bạn làm cho nó một chức năng không có khuôn mẫu, nó sẽ hoạt động (http://ideone.com/zIIGb). Mặc dù nó là cồng kềnh để đảm bảo cùng một thứ tự. – Nobody

+0

@Nobody: Bạn nói đúng. Tôi sẽ cập nhật hoặc xóa tại một số thời điểm. –

0

Cách tiếp cận dễ dàng có thể là chỉ chia sẻ cùng một lớp trong cả hai chương trình.

Tái sử dụng là một trong những mục tiêu để OOP.

Lớp học đóng gói bản đồ và khởi tạo của nó có thể được tạo và sau đó được sử dụng trong cả hai chương trình C++.

Các vấn đề liên quan