什么是第一 - 模板实例化与宏扩展?
我们来看一个这样的代码示例(它只是一个结合define
和template
的人为示例,不要寻找任何意义它):
Let's consider a code example like this (it is just an artificial example to combine define
and template
, don't look for any sense it it):
#define COMMA ,
template <typename A> class Test
{
public:
Test(){}
void Foo(A var COMMA int test);
};
Test<int> Knarz;
问题:
我的假设是否正确,首先预处理器将搜索/替换所有出现的 COMMA,第二编译器将按该顺序实例化任何模板?
Is my assumption correct that, first the preprocessor will search/replace all occurrences of COMMA and second the compiler will instantiate any templates in that order?
跟进:
如果上面的答案是'是',正如我希望的那样,你能解释一下为什么这个使用模板和定义的解决方案有效吗?
If the above answer is 'yes', as I hope it to be, can you explain why this solution using templates and defines works?
推荐答案
预处理器在编译本身完成之前运行,因此您假设预处理器将在模板实例化之前替换 COMMA
是正确.
The preprocessor is run before the compiling itself is done, so your assumption that the preprocessor will replace COMMA
before the template is instantiated is correct.
为了您的后续行动:该解决方案与模板关系不大.问题在于预处理器将大括号内的逗号作为宏的参数分隔符,因为它不会解析 C++ 代码以查看它是模板参数的分隔符.因此,COMMA
宏仅在 MOCK_CONSTANT_METHOD0
被替换后才用于插入 ,
以分隔模板参数.但是我不确定这是否可以保证工作,因为我不知道内存宏替换顺序的保证.如果 COMMA
将在 MOCK_CONSTANT_METHOD0
之前被替换,那么一切都会崩溃并且代码再次无法编译.
For your followup:
The solution has little to do with templates. The problem there is that the preprocessor will take commas inside the braces to be argument separators for the macro, since it doesn't parse the C++ code to see that it is the separator for the template arguments. So the COMMA
macro is used to insert the ,
for separating template arguments only after the MOCK_CONSTANT_METHOD0
has been substituted. I am however not sure if this is guaranteed to work, since I don't know the guarantees for the order of macro-substitution by memory. If COMMA
would be substituted before MOCK_CONSTANT_METHOD0
everything falls apart and the code once again doesn't compile.
查看标准后,我认为该解决方案通常应该有效,因为预处理器会首先找到 MOCK_CONSTANT_METHOD0
并替换它.只有这样,它才会检查替换结果以找到 COMMA
宏.但不能保证.
After looking into the standard I think the solution should generally work, since the preprocessor will find MOCK_CONSTANT_METHOD0
first and replace it. Only then will it examine the result of the replacement to find the COMMA
macro. No guarantees though.
相关文章