我需要记录(出于审计/日志目的)在我的代码中传递的 lambda 函数的代码。当然,lambda 对象也需要保存。所以我想出了一个宏解决方案如下:

#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 定义中的换行符不见了(实际上我的 lambda 表达式比上述原型(prototype)示例中的要长得多,因此出于可读性的原因需要保留换行符)。关于如何保留它们的任何想法? (C++11 很好)。

谢谢!

最佳答案

如果我没记错的话,新行甚至不是传递给宏的参数的一部分。它与空白折叠相对于宏扩展的顺序有关,实际上空白在预处理器标记化期间被剥离。

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。

关于保留换行符的 C++ 预处理器字符串化?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/19741257/

10-13 08:31