Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 首先是什么-模板实例化与宏扩展? 让我们来考虑这样的代码示例(它只是一个虚构的例子来组合定义< /代码>和模板,不要寻找它的任何意义): #定义逗号, 模板类测试 { 公众: Test(){} void Foo(变量逗号int测试); }; 测试克纳兹;_C++_Templates_Macros_C Preprocessor - Fatal编程技术网

C++ 首先是什么-模板实例化与宏扩展? 让我们来考虑这样的代码示例(它只是一个虚构的例子来组合定义< /代码>和模板,不要寻找它的任何意义): #定义逗号, 模板类测试 { 公众: Test(){} void Foo(变量逗号int测试); }; 测试克纳兹;

C++ 首先是什么-模板实例化与宏扩展? 让我们来考虑这样的代码示例(它只是一个虚构的例子来组合定义< /代码>和模板,不要寻找它的任何意义): #定义逗号, 模板类测试 { 公众: Test(){} void Foo(变量逗号int测试); }; 测试克纳兹;,c++,templates,macros,c-preprocessor,C++,Templates,Macros,C Preprocessor,问题: 我的假设正确吗,第一个预处理器将搜索/替换所有出现的逗号,第二个编译器将按照该顺序实例化任何模板 跟进: 如果上面的答案是“是”,正如我所希望的那样,你能解释一下为什么这样做吗?第一个宏和之后的模板,实际上宏只会在编译之前对现有代码应用更改。因此,在此解决方案中,逗号将生成如下模板代码: MOCK_CONSTANT_METHOD0(aMethod, const QMap<QString,QString>()); MOCK_CONSTANT_METHOD0(method,co

问题:

我的假设正确吗,第一个预处理器将搜索/替换所有出现的逗号,第二个编译器将按照该顺序实例化任何模板

跟进:


如果上面的答案是“是”,正如我所希望的那样,你能解释一下为什么这样做吗?

第一个宏和之后的模板,实际上宏只会在编译之前对现有代码应用更改。因此,在此解决方案中,逗号将生成如下模板代码:

MOCK_CONSTANT_METHOD0(aMethod, const QMap<QString,QString>());
MOCK_CONSTANT_METHOD0(method,const QMap());
在汇编之前

因此,关于第二个问题:


这与gmock框架的工作原理有关,实际上MOCK_CONSTANT_METHOD0是一个宏,因此该行将转换为其他行。Markus Mayr说逗号将被翻译成一个参数分隔符,因此它与gmock宏如何转换有关。在这种情况下,我想首先将替换模拟宏,然后在内部应用逗号,这就是为什么它可以与宏一起工作,而不仅仅是与逗号一起工作的原因。

预处理器是在编译完成之前运行的,因此您假设在实例化模板之前预处理器将替换逗号是正确的

为您的后续行动: 解决方案与模板几乎没有关系。问题在于,预处理器将在括号内使用逗号作为宏的参数分隔符,因为它不解析C++代码,以查看它是模板参数的分隔符。因此,只有在替换了
MOCK\u CONSTANT\u METHOD0
之后,才会使用
COMMA
宏插入用于分隔模板参数的
。但是,我不确定这是否保证有效,因为我不知道内存对宏替换顺序的保证。如果在
MOCK_CONSTANT_METHOD0
之前替换
COMMA
,则所有内容都会崩溃,代码再次无法编译


编辑:在研究了标准之后,我认为解决方案通常应该有效,因为预处理器将首先找到
MOCK\u CONSTANT\u METHOD0
并替换它。只有这样,它才会检查替换的结果以找到
逗号
宏。但是没有保证。

预处理器是第一位的

我认为引用的解决方案是一个非常糟糕的主意,因为它取决于预处理器执行替换的顺序。由于整个字符仅用于防止预处理器在模板参数列表中被逗号阻塞,因此最好使用typedef。

我的假设正确吗?首先,预处理器将 搜索/替换所有出现的
逗号
,然后编译器将 按该顺序实例化任何模板

逗号
标记在第4阶段被替换。

模板将在第8阶段实例化。

谢谢您的回答。你能看一看我的后续问题吗,这是更有趣的部分:-)@RonaldMcBean:为你的后续问题添加了一些解释。这回答了你的问题吗?我想这是肯定的,因为宏扩展是递归工作的——扩展、重新分析、扩展(如果还没有扩展)这个确切的标记。@Grizzly:是的,它回答了我的问题。非常感谢你的帮助!谢谢你的回答。你能看一看我的后续问题吗,这是更有趣的部分:-),但是你答案中的代码没有编译(参见参考问题)。但有了定义,它就是在编译。为什么?我同意引用的解决方案是个坏主意。但我想知道为什么它会起作用!正如我所说,这取决于预处理器执行的替换顺序。在它工作的情况下,预处理器首先替换MOCK_CONSTANT_METHOD0宏,然后替换逗号宏。如果它反过来做,事情就会分崩离析。
MOCK_CONSTANT_METHOD0(aMethod, const QMap<QString,QString>());