2012-04-30 31 views
10

Possible Duplicate:
Creating C macro with ## and LINE (token concatenation with positioning macro)Tạo macro bằng __LINE__ cho tên biến khác nhau

Tôi cố gắng để sử dụng __LINE__ vĩ mô để tạo ra tên biến khác nhau. Tôi có một lớp tiêu chuẩn scoped gọi là Benchmark (nằm trong không gian tên utils) và constructor của nó có một chuỗi. Dưới đây là định nghĩa vĩ mô tôi đã tạo:

#define BENCHMARK_SCOPE utils::Benchmark bm##__LINE__(std::string(__FUNCTION__)) 

Đáng tiếc là điều này gây ra các lỗi sau:

<some_file_name>(59): error C2374: 'bm__LINE__' : redefinition; multiple initialization

Điều này dẫn tôi đến kết luận các __LINE__ macro không được mở rộng. Tôi đã tạo macross của tôi theo this post. Bạn có ý tưởng tại sao __LINE__ không được mở rộng?

EDIT: có thể thông tin trình biên dịch cũng có liên quan. Tôi đang sử dụng visual studio 2010.

+0

Hmm. Bạn đã thử 'bm ## __LINE__' (với một khoảng trống) chưa? – Cameron

+0

@Cameron Tôi đã cảm ơn nhận xét của bạn nhưng không có gì thay đổi. –

+0

OK, thêm một lần nữa để thử: '#define _BENCHMARK_SCOPE (dòng) utils :: Benchmark bm ## line (...' với '#define BENCHMARK_SCOPE _BENCHMARK_SCOPE (__ LINE __)' – Cameron

Trả lời

13

Bạn cần phải sử dụng sự kết hợp của 2 macro:

#define COMBINE1(X,Y) X##Y // helper macro 
#define COMBINE(X,Y) COMBINE1(X,Y) 

Và sau đó sử dụng nó như là,

COMBINE(x,__LINE__); 
+0

Bạn có ý tưởng tại sao tôi cần phải sử dụng hai macro cho điều đó không? –

+1

@izomorphius, Trên thực tế câu hỏi của bạn là một bản sao của một số khác, nơi nó được giải thích độc đáo.Tôi đã nhận xét rằng câu hỏi của bạn, plz kiểm tra xem nó. – iammilind

5

thử mã này, tôi đã sử dụng nó trong một dự án cũ

#define CONCATENATE_DIRECT(s1, s2) s1##s2 
#define CONCATENATE(s1, s2) CONCATENATE_DIRECT(s1, s2) 
#ifdef _MSC_VER // Necessary for edit & continue in MS Visual C++. 
# define ANONYMOUS_VARIABLE(str) CONCATENATE(str, __COUNTER__) 
#else 
# define ANONYMOUS_VARIABLE(str) CONCATENATE(str, __LINE__) 
#endif 


int ANONYMOUS_VARIABLE(var) 

EDIT:

Tôi nghĩ rằng bạn nên sử dụng COUNTER trong visual studio chỉ khi cũng sử dụng các tiêu đề được biên dịch trước.

+0

Nó cũng làm việc với __LINE__ –

3

Bạn đang sử dụng dán thẻ. Điều này xảy ra trước macro đệ quy mở rộng (để bạn có thể mã thông báo dán để lấy tên macro bạn muốn gọi). Như vậy:

#define PASTE(a,b) a ## b 

sẽ dán những lập luận chính xác thông qua với PASTE, sau đó cố gắng mở rộng kết quả mã mới. Để có được hiệu quả mong muốn, bạn cần một mức bổ sung gián tiếp:

#define PASTE_HELPER(a,b) a ## b 
#define PASTE(a,b) PASTE_HELPER(a,b) 

Ở đây, các đối số PASTE sẽ được mở rộng trước khi PASTE_HELPER là gọi.

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