有没有办法通过C++宏和模板
std::map<std::string, float>
作为参数传递给宏?
(问题是, “” 用于由宏分裂
std::map<std::string
和
float>
作为独立参数。我想避免这种情况。
有没有办法通过C++宏和模板
std::map<std::string, float>
作为参数传递给宏?
(问题是, “” 用于由宏分裂
std::map<std::string
和
float>
作为独立参数。我想避免这种情况。
一个不起眼的解决方法是“隐藏”另一个宏内的逗号
#define ARGUMENT std::map<std::string, float>
YOUR_MACRO(ARGUMENT)
#undef ARGUMENT
但是,如果YOUR_MACRO
本身需要将其另一个级别传播到另一个宏,它将遇到同样的问题。
'typedef'克服了嵌套宏问题,但更具永久性。 – 2010-02-19 08:42:42
我第二种'typedef'方法。每当有一个替代品不涉及一个宏并提供相同的易用性......你最好没有一个宏。 – 2010-02-19 09:32:06
哦,真是太酷了。如果可以的话,我会给你+10。谢谢! – 2013-02-08 07:40:37
不,没有办法做到这一点,缺少使用typedef。例如,BOOST_FOREACH遭受同样的问题。
+1使用typedef – James 2010-02-19 09:32:21
有几种方法,如果你需要进行一些预处理编程。尽管这可能会给用户带来一些负担,这取决于你所追求的内容,并且需要对宏进行量身定制来处理它......查看我的答案。 – 2010-02-19 09:33:42
尝试使用模板而不是宏。
斯科特迈尔斯:C++有效 项目2:不想consts,枚举和内联到#define语句
'项目2'在这里不适用:它没有提到模板,只是常量......虽然我同意一般的观点,但如果它总是可能的话......那将会很棒。 – 2010-02-19 09:14:54
它是第2项的内联。我在这里提到模板,因为宏不关心类型,这就是为什么你通常不能用普通函数替换它们。但是使用模板可以让你做到这一点。我认为迈尔使用最小/最大宏对模板进行演示。 – Totonga 2010-02-19 09:55:24
我有类似的东西在几个月前,如果你使用宏的,并有包含参数的逗号(“” ),你需要包裹于额外parenthasis即:
#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);
是的,有一种方法,它是间接的。
正如你所说,一个宏在其解释中相当愚蠢。但它仍然认可括号。
实施例: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";
所以,是的,它是可能的,但宏必须是明确定制来处理它。
我还应该补充一点,它可能很麻烦,因为用户需要计算',':/ – 2010-02-19 09:36:29
是的,只要您能安排它,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>);
我认为他们听说你第一次...... – 2010-02-19 08:38:23
难道这就是为C?还是C++? – AnT 2010-02-19 08:39:43
只是好奇,我们可以看到有问题的宏吗?可能有更好的方法来完成你使用它的任何任务。 – 2010-02-19 08:43:16