有没有一种方法可以传递参数?
作为宏的参数?
(问题在于“,”被宏用来分隔。)
std::map<std::string, float>
作为宏的参数?
(问题在于“,”被宏用来分隔。)
std::map<std::string
并且
float>
作为单独的参数。我希望避免这种情况。
不,除非使用typedef,否则没有办法做到这一点。例如,BOOST_FOREACH也存在同样的问题。
是的,有一种方法,不过这是一种间接的方法。
正如你所说,宏在解释时相当简单。不过它仍然能够识别括号。
例如:BOOST_MPL_ASSERT((boost::is_same<int,int>))
它通过使用另一个层次的括号来工作,从宏的角度形成一个Tuple
。
如果您使用Boost.Preprocessor库,您可以轻松地“展开”一个Tuple
以获取其内容。不幸的是,您需要预先知道元组的大小,因此需要一个额外的参数。
#define MY_MACRO(Size, TemplatedType, Name)\
BOOST_PP_TUPLE_REM(Size)(TemplatedType) Name
并且在实际操作中:
MY_MACRO(2, (std::map<int,std::string>), idToName);
// expands to 'std::map<int,std::string> idToName'
idToName[1] = "Smith";
#define ARGUMENT std::map<std::string, float>
YOUR_MACRO(ARGUMENT)
#undef ARGUMENT
然而,如果YOUR_MACRO
本身需要将其传播到另一个宏中的下一级,则会遇到相同的问题。
typedef
可以解决嵌套宏的问题,但是它更加永久。 - Chris Lutztypedef
的方法。每当有一种不涉及宏且提供相同易用性的替代方案时...你最好不要使用宏。 - Matthieu M.std::map<std::string, float>
作为你的最后一个或唯一的参数。只需使用__VA_ARGS__
,例如:#define MAKE_A_NEW_ONE_OF_THESE(a, ...) __VA_ARGS__ *a = new __VA_ARGS__
MAKE_A_NEW_ONE_OF_THESE(pMyMap, std::map<std::string, float>);
#define DEF(ret,conv,name,args) typedef ret (conv * name)(args)
//usage
DEF(void,__cdecl,Foo,(int a1, string a2));
这个方法可能与某些事情冲突/在某些情况下无效,就像这个例子一样(它会导致它变成一个无效的C风格转换):
#define MY_VAR(type,name) type name
//usage
MY_VAR((std::map<std::string, float>),Map);
不过有一种解决这个问题的方法,但需要你的编译器支持可变参数宏(GCC|MSVC):
#define _W(...) __VA_ARGS__
#define VAR(x,y) x y
VAR(_W(std::map<std::string, float>),Map);
args
,因为它已经带有括号了。 - Matthieu M.(std::map<std::string, float>) Map;
,但这实际上会导致编译错误(因为它将 C 风格的转换应用于未声明的标识符 Map)。 - UncleBens
map
,我会说是C++
...不是吗? - Matthieu M.