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;
Question:
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?
Followup:
If the above answer is 'yes', as I hope it to be, can you explain why this solution using templates and defines works?
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.
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.
Edit: 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.
First macros and template after, actually macros will just apply the changes on the existing code before the compilation. So in this solution the comma will generate a template code like:
MOCK_CONSTANT_METHOD0(aMethod, const QMap<QString,QString>());
before the compilation.
So for the second question:
It is related with how the gmock framework works actually the MOCK_CONSTANT_METHOD0 is a macro so the line will be transformed to something else. Markus Mayr said that comma will be translated as a parameter separator so it is related with a how the gmock macros will be transformed in this case I guess that first the mock macro will be replaced and after the comma will be applied internally and this is the reason why it does work with a macro and not just with a comma.
The preprocessor is first.
I think the referenced solution is a pretty bad idea as it depends on the order by which the preprocessor performs its substitutions. Since the whole charade is only used to prevent the preprocessor from choking on the comma in the template argument list, it would be much better to use a typedef.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With