问题
I have some code that essentially condenses down to
#define FOO(a)
FOO(std::map<int, int>);
But it emits a compile error (too many actual parameters for macro FOO
).
Obviously the preprocessor is thinking that I've supplied std::map<int
and int>
as arguments.
Is there a way round this? The preprocessor will not treat a quoted string with a comma in this way.
回答1:
This should perhaps ideally be a comment, but SO doesn't support code in comments, so, you can do
#include <map>
#define T_ARGS( ... ) < __VA_ARGS__ >
#define FOO( a ) a x;
auto main() -> int
{
FOO( std::map T_ARGS( int, int ) );
(void) x;
}
or you can define a macro that resolves to comma, or you can use just about any scheme that's specific to some particular use case (e.g., passing template name separately).
回答2:
The comma is being treated as a macro argument seperator, it does not do this with commas within parenthesizes.
If you are using Boost, they provide BOOST_PP_COMMA:
#include <boost/preprocessor/punctuation/comma.hpp>
#define FOO(a)
FOO(std::map<int BOOST_PP_COMMA int>);
You can also define your own:
#define COMMA ,
FOO(std::map<int COMMA int>);
回答3:
The preprocessor will only treat unparenthesised commas as a macro argument separator. So what you can do is rewrite std::map<int, int>
into something that has parentheses around it. A simple one might be decltype(std::map<int, int>())
.
回答4:
Just add an extra set of parentheses:
#define FOO(a)
FOO((std::map<int, int>));
来源:https://stackoverflow.com/questions/32460599/passing-a-template-which-requires-a-comma-to-a-single-argument-macro