2013-11-02 62 views
4

我需要記錄(用於審計/日誌記錄的目的)在我的代碼中傳遞的lambda函數的代碼。當然,lambda對象也需要保存。所以,我想出了一個宏觀的解決方案如下:保留新行的C++預處理器字符串化?

#define LAMBDA_AND_STRING(lambda) lambda, #lambda 

using namespace std; 

int main(int argc, const char * argv[]) 
{ 
    auto p = pair<function<void()>, string> (LAMBDA_AND_STRING([] { 
     cout << "Hello world!" << endl; 
     cout << "Hello again!"; 
    })); 

    cout << "CODE:" << endl << p.second << endl << endl; 

    cout << "EXECUTION:" << endl; 
    p.first(); 
    cout << endl; 

} 

此輸出:

CODE: 
[] { cout << "Hello world!" << endl; cout << "Hello again!"; } 

EXECUTION: 
Hello world! 
Hello again! 

這幾乎是良好的,但是從拉姆達定義的換行符都走了(實際上我lambda表達式要長得多比在上面的典型例子中,所以爲了可讀性需要保持換行符)。任何想法如何保持他們? (C++ 11很好)。

謝謝!

回答

3

如果我沒有記錯,新行甚至不是傳遞給宏的參數的一部分。這與相對於宏擴展發生空白摺疊的順序有關,並且實際上在預處理器標記化期間空白區被剝離。

Foo.cpp中:

#define FOO(a) a 

FOO(
    one 
    two 
    three 
) 

結果:

$ gcc -E foo.cpp 
# 1 "foo.cpp" 
# 1 "<command-line>" 
# 1 "foo.cpp" 


one two three 

所以,你的運氣了,我想。你可以做一些真的壞壞地解決它:

#define LAMBDA_AND_STRING(lambda) lambda, #lambda 
#define NEWLINE 

LAMBDA_AND_STRING([] { NEWLINE 
    cout << "Hello world!" << endl; NEWLINE 
    cout << "Hello again!"; NEWLINE 
}) 

預處理到:

[] { cout << "Hello world!" << endl; cout << "Hello again!"; }, "[] { NEWLINE cout << \"Hello world!\" << endl; NEWLINE cout << \"Hello again!\"; NEWLINE }" 

打印之前現在更換NEWLINE S中的字符串中。

+0

使用';;'作爲行分隔符怎麼樣?沒有宏,更短,更清晰,對原始來源沒有影響。 –

+0

@tehinternetsismadeofcatz:它不會影響這個源,但它會影響例如一個調用具有多個詳細參數的算法,該算法已被分成多行。 –

+0

這是一個很好的觀點。 –