Vâng, không chỉ bộ tiền xử lý phải được sử dụng - nhưng nó sẽ không được nhìn thấy đối với người dùng cuối.
Khi bạn muốn BASENAME()
được sử dụng trong một số tập tin - sử dụng tập tin tiêu đề này basename.h
:
// basename.h
#include <string.h>
static size_t basename_start_calc(const char* filename)
{
const char* base = strrchr(filename, '/');
return base ? (base - filename + 1) : 0;
}
static inline size_t basename_start(const char* filename)
{
static size_t retval = basename_start_calc(filename);
return retval;
}
#define STR_(t) #t
#define STR(t) STR_(t)
#define BASENAME() ((__FILE__ ":" STR(__LINE__)) + basename_start(__FILE__))
Một ideone example here.
basename_start(__FILE__)
sẽ chỉ được đánh giá một lần cho tệp nguồn đã cho. Rất tiếc, bạn không thể sử dụng giải pháp này trong các tệp tiêu đề - chỉ trong các tệp nguồn. Bạn có thể thay đổi nó, vì vậy nó có thể được sử dụng ở khắp mọi nơi - nhưng sau đó bắt đầu đường cơ sở cho tên tập tin đã cho sẽ được tính toán mỗi lần. Chỉ cần sử dụng trong BASENAME()
basename_start_calc(__FILE__)
thay vì basename_start(__FILE__)
...
Tôi tin rằng điều này là tốt nhất bạn có thể tự động.
Tất nhiên bạn có thể xác định bằng tay trong mỗi vĩ mô file:
#define BASENAME() ("somefile.cpp:" STR(__LINE__))
nhưng tôi không chắc chắn đây là những gì bạn muốn ....
là C++ 11 ok? Phải chuỗi có thể sử dụng trong bộ tiền xử lý, hoặc chỉ trong thời gian biên dịch? – kennytm
@KennyTM Không, tôi không thể sử dụng C++ 11. Tôi muốn nó ở thời gian biên dịch. Boost cũng tốt. –
Hoặc không sử dụng '__FILE__', nhưng xác định chuỗi ký tự của riêng bạn ở đầu mỗi tệp quan tâm. – chill