2010-02-20 27 views
5

Given:C luận vĩ mô 'lưu trữ'

#define f(x, y) (x+y) 
#define g(x, y) (x*y) 
#define A 1, 2 
#define B 2, 3 

int main() { 
    int a = f(A); 
    int b = g(A); 
    int c = f(B); 
    int d = g(B); 
} 

mà không làm việc,

làm thế nào tôi có thể làm cho nó hoạt động? Ý tưởng cơ bản là tôi có một danh sách các đối số mà tôi muốn chuyển tới hai macro khác nhau, mà không lặp lại danh sách các đối số dài mỗi lần.

Có cách nào để thực hiện việc này không? [Bạn được quyền sửa đổi f & g; bạn thậm chí còn được chào đón để sửa đổi A & cách tôi gọi các macro. Các yêu cầu duy nhất là: 1) danh sách arguemnt chỉ có thể xuất hiện một lần 2) nó không thể được mã hóa cứng ... để tôi có thể gọi các macro với các đối số khác nhau

Nếu bạn là giải pháp không khá công việc nhưng 'hầu hết các công trình' (đối với bạn định nghĩa gần như), tôi cũng muốn nghe nó, có lẽ tôi có thể làm cho nó hoạt động.

Cảm ơn!

Chỉnh sửa: f & g phải là macro. Họ nắm bắt các tên biểu tượng và thao túng chúng.

+0

Nếu bạn thay đổi các yêu cầu của câu hỏi ban đầu của bạn, vui lòng cung cấp một ví dụ phù hợp cho thấy những gì bạn thực sự muốn. –

Trả lời

3

EDIT: Một phiên bản làm việc với chưa sửa đổi AB

#define f(x, y) (x+y) 
#define g(x, y) (x*y) 
#define A 1, 2 
#define B 2, 3 

#define APPLY2(a, b) a b 
#define APPLY(a, b) APPLY2(a, (b)) 

int main(int argc, char* argv[]) 
{ 
    int x= APPLY(f, A); 
    int y= APPLY(f, B); 
    int z= APPLY(g, A); 
    int d= APPLY(g, B); 

    return 0; 
} 
+0

Điều này thật khéo léo. Bất kỳ ai hiểu được sẽ đưa ra câu trả lời này. – anon

+0

Tại sao lại có thêm sự không đồng ý? '#define APPLY (a, b) a (b)' cũng hoạt động tốt. –

+0

@ Chris, nó không hoạt động theo cách đó. Tôi quên rason chính xác, nhưng MSVC chắc chắn phàn nàn về nó. – MSN

4

Bạn có thể làm điều này:

static int f(int x, int y) { return (x+y); } 
static int g(int x, int y) { return (x*y); } 
#define A 1, 2 
#define B 2, 3 

Nếu bạn đang sử dụng một trình biên dịch C được hỗ trợ một chuẩn inline chỉ thị, bạn có thể loại bỏ các chi phí của một cuộc gọi chức năng. Và nếu bạn đang sử dụng C++,

template<T> T f(T x, T y) { return (x+y); } 
template<T> t g(T x, T y) { return (x*y); } 
#define A 1, 2 
#define B 2, 3 

sẽ hoạt động gần giống như giải pháp macro dự kiến ​​của bạn.

Nếu fgphải được macro, không có cách nào với tiền xử lý C để vượt qua nhiều đối số cho các macro mà không có một dấu phẩy thực tế xuất hiện tại địa điểm gọi. Để thực hiện điều đó, bạn sẽ phải thêm mức tiền xử lý trước trên bộ tiền xử lý C.

+0

Giải pháp tốt. Ngoài ra, ngay cả khi không có chỉ thị nội tuyến, miễn là bạn sử dụng chỉ thị tĩnh trên các hàm, tối ưu hóa các trình biên dịch có khả năng sẽ tự động điền nội tuyến. –

+0

"một chỉ thị nội tuyến không chuẩn". Đối với vấn đề đó nếu nó hỗ trợ một tiêu chuẩn, nó có thể sẽ nội tuyến một cái gì đó đơn giản này.Chúng tôi biết người hỏi đang sử dụng C99, vì chức năng chính của anh ta không có câu trả lời, nhưng có lẽ là có ý định hành vi ;-) –

0

Có lẽ đây là những gì bạn muốn:

#include<iostream> 
using namespace std; 

#define A 1, 2 

template <typename T> 
inline T f(T a, T b) { return a + b; } 

int main() 
{ 
    cout << f(A) << endl; 
    return 0; 
} 
+1

Câu hỏi là về C, phải không? –

4

Nếu bạn đang sử dụng C99, bạn có thể sử dụng compound initialiser syntax để làm điều này bằng cách thông qua nhiều đối số là một mảng duy nhất:

#define f(a) (a[0]+a[1]) 
#define g(a) (a[0]*a[1]) 
#define A ((int[]) {1, 2}) 
#define B ((int[]) {2, 3}) 

GCC hỗ trợ cú pháp ngữ pháp này trong cả hai chế độ C89 và C++.

+0

Thx để phân loại điều này :) – mre

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