2011-02-05 37 views
11

Tôi muốn làm điều gì đó như sau:Làm cách nào để tạo danh sách qua bộ tiền xử lý C (cpp)?

F_BEGIN 

F(f1) {some code} 
F(f2) {some code} 
... 
F(fn) {some code} 

F_END 

và có nó tạo ra sau

int f1() {some code} 
int f2() {some code} 
... 
int fn() {some code} 

int (*function_table)(void)[] = { f1, f2, ..., fn }; 

Các chức năng chính họ là dễ dàng. Những gì tôi không thể làm là để theo dõi tất cả các tên cho đến khi kết thúc cho function_table.

Tôi đã xem số this questionthis question nhưng tôi không thể nhận được bất kỳ thứ gì phù hợp với mình. Bất kỳ ý tưởng nào?

Trả lời

14

Cách thông thường để thực hiện việc này với bộ tiền xử lý là xác định tất cả các hàm trong macro cần macro khác làm đối số và sau đó sử dụng các macro khác để trích xuất những gì bạn muốn. Ví dụ:

#define FUNCTION_TABLE(F) \ 
    F(f1, { some code }) \ 
    F(f2, { some code }) \ 
    F(f3, { some code }) \ 
: 

    F(f99, { some code }) \ 
    F(f100, { some code }) 

#define DEFINE_FUNCTIONS(NAME, CODE)  int NAME() CODE 
#define FUNCTION_NAME_LIST(NAME, CODE) NAME, 

FUNCTION_TABLE(DEFINE_FUNCTIONS) 
int (*function_table)(void)[] = { FUNCTION_TABLE(FUNCTION_NAME_LIST) }; 
+0

Trình tiền xử lý C không cho phép các macro xác định các macro khác hoặc có bất kỳ cách nào để thực hiện đệ quy hoặc lặp, do đó kỹ thuật này (cũng được mô tả bởi ddyer) là tốt nhất bạn có thể thực hiện. – zwol

0

Tăng là thư viện C++, nhưng mô-đun Preprocessor của nó vẫn tốt để sử dụng trong C. Nó cung cấp một số loại dữ liệu nâng cao đáng kinh ngạc và chức năng để sử dụng trong bộ tiền xử lý. Bạn có thể kiểm tra xem nó ra.

+0

Tôi muốn làm điều này chỉ với cpp. –

+0

Và [Boost :: Preprocessor] (http://www.boost.org/doc/libs/1_38_0/libs/preprocessor/) là bộ xử lý trước C thuần túy (cũng như bộ xử lý trước C++). –

1

Đây là loại lạm dụng CPP nhưng loại lạm dụng phổ biến. Tôi xử lý tình huống như thế này bằng cách định nghĩa các macro giả

#define FUNCTIONS \ 
foo(a,b,c,d) \ 
foo(a,b,c,d) \ 
foo(a,b,c,d) 

now, 

#define foo(a,b,c,d) \ 
a+b ; 

FUNCTIONS 

#undef foo 

sau, khi bạn muốn một cái gì đó khác nhau thực hiện với cùng một danh sách

#define foo(a,b,c,d) \ 
a: c+d ; 

FUNCTIONS 

#undef foo 

Đó là một chút xấu xí và cồng kềnh, nhưng nó hoạt động.

+1

Ít xấu xí hơn nếu bạn thực hiện 'foo' một đối số cho' FUNCTIONS' thay vì đi PHP khắp nơi. –

5

Nếu bạn có trình biên dịch tuân thủ C99, bộ tiền xử lý có danh sách đối số độ dài thay đổi. P99 có một bộ tiền xử lý P99_FOR có thể thực hiện "hủy bỏ mã" giống như bạn muốn đạt được. Ở gần dụ bạn

#define MYFUNC(DUMMY, FN, I) int FN(void) { return I; } 
#define GENFUNCS(...)           \ 
P99_FOR(, P99_NARG(__VA_ARGS__), P00_IGN, MYFUNC, __VA_ARGS__) \ 
int (*function_table)(void)[] = { __VA_ARGS__ } 

GENFUNCS(toto, hui, gogo); 

sẽ mở rộng như sau (chưa được kiểm tra)

int toto(void) { return 0; } 
int hui(void) { return 1; } 
int gogo(void) { return 2; } 
int (*function_table)(void)[] = { toto, hui, gogo }; 
Các vấn đề liên quan