2015-07-10 43 views
1

我想寫一個日誌函數或宏,它可以接受其他回調函數作爲參數,並在裏面運行回調函數,記錄運行時和名稱。 但回調函數可能有不同的參數類型和數量,我不想明確地將回調函數名作爲參數傳遞。實現一個登錄函數或宏可以登錄日期和函數名

我嘗試使用std ::綁定和std ::功能

void log(std::function<void()> callbackFunc){ 
     //assuming all callbackFunc return type is void 
     struct timeval tmBegin, tmEnd; 
     gettimeofday(&tmBegin); 
     callbackFunc(); 
     gettimeofday(&tmEnd); 
     //then write tmEnd - tmBegin to file 
     //but i dont know how to get callbackFunc's name} 

void callbackFunc1(int); 
void callbackFunc2(int ,char, string); 
log(std::bind(callbackFunc1, 1)); 
log(std::bind(callbackFunc2, 2, 'c', "test")); 

除此之外,也許回調函數具有不同的返回類型,可以實現這樣的日誌功能?

+1

你有沒有看着可變參數模板(因爲C++ 11),例如在http://eli.thegreenplace.net/ 2014/variadic-templates-in-c/ – jensa

+0

這不是'C' ...將其刪除。 –

回答

2

的函數的名稱(和變量等等)編譯時會丟失。編譯器沒有(真的)知道函數的名字。您可以使用__FUNCTION__來獲取您所在功能的名稱,但在這種情況下無效。你也許可以用一個代替bind的宏來做些什麼,或者簡單的解決方法是隻傳遞一個字符串和作爲log的參數的函數。

宏解決方案更復雜,因爲你必須處理變量參數,但像這樣的工作):

#define LOG(f, ...) log(std::bind(f, __VA_ARGS__), #f) 

和修改log到:

void log(std::function<void()> callbackFunc, const char* name) 

編輯:不同返回類型可以通過使log爲模板化函數來處理,並使用模板作爲std::function返回類型中的類型參數:

template<typename RET> 
void log(std::function<RET()> callbackFunc) 

(我沒有測試過這一點,但我相信它會工作)

+0

這是怎麼發生的?我們有幾乎相同的答案,在同一時間:-) – Amit

+0

謝謝,它的工作原理。順便說一句,如果回調函數具有不同的返回類型,如何傳入並處理返回 – cavehubiao

+0

@Amit:時常發生 - 爲變量等選擇顯而易見的名稱將與它非常相似。 –

0

你可以換一個可變參數宏日誌調用(如你「猜」)搶參數本身(函數地址),以及它的名字:

#define log(f, ...) _log(std::bind(f, __VA_ARGS__), #f) 

void _log(std::function<void()> callbackFunc, const char *fName){ 
    // ... 
} 

log(callbackFunc1, 1);