2013-11-02 2 views
4

Мне нужно записать (для целей аудита/ведения журнала) код лямбда-функций, которые передаются в моем коде. Конечно, объект лямбда также должен быть сохранен. Так что я придумал макросъемки решения следующим образом:Строка препроцессора 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! 

Это почти хорошо, но новые строки из определения лямбды ушли (на самом деле мои лямбды гораздо больше чем в вышеупомянутом прототипном примере, поэтому сохранение новых строк необходимо для удобства чтения). Любые идеи о том, как их сохранить? (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

Это хороший момент. –

Смежные вопросы