C++ C++;宏和模板

C++ C++;宏和模板,c++,macros,C++,Macros,有路过去吗 std::map<std::string, float> 作为单独的论点。我希望避免这种情况。一种不雅观的解决方法是在另一个宏中“隐藏”逗号 #define ARGUMENT std::map<std::string, float> YOUR_MACRO(ARGUMENT) #undef ARGUMENT #定义参数std::map 您的_宏(参数) #未定义参数 但是,如果您的_宏本身需要将它传播到另一个宏的另一个级别,它将遇到相同的问题。不,除了使

有路过去吗

std::map<std::string, float>

作为单独的论点。我希望避免这种情况。

一种不雅观的解决方法是在另一个宏中“隐藏”逗号

#define ARGUMENT std::map<std::string, float> 
YOUR_MACRO(ARGUMENT)
#undef ARGUMENT
#定义参数std::map
您的_宏(参数)
#未定义参数

但是,如果您的_宏本身需要将它传播到另一个宏的另一个级别,它将遇到相同的问题。

不,除了使用typedef之外,没有其他方法可以做到这一点。例如,BOOST_FOREACH也遇到同样的问题。

尝试使用模板而不是宏

< Scott Meyers >有效C++
第2项:更喜欢常量、枚举和内联线而不是#defines

几个月前,我有类似的东西,如果您使用的是宏且参数包含逗号(“,”),则需要将它们封装在额外的parenthasis中,即:

#define DEF(ret,conv,name,args) typedef ret (conv * name)(args)

//usage
DEF(void,__cdecl,Foo,(int a1, string a2)); 
此方法可能与某些内容冲突/在某些情况下无效,如本例(它导致它成为无效的c样式转换):

#定义我的变量(类型、名称)类型名称
//用法
我的变量((标准::映射),映射);
虽然有一种方法可以解决这个问题,但它要求编译器支持可变宏(|):

#定义_W(…)_VA_参数__
#定义VAR(x,y)xy
VAR(W(std::map),map);

是的,有一种方法,不过是间接的

正如您所说,宏的解释相当愚蠢。然而,它仍然可以识别括号

示例:
BOOST\u MPL\u断言((BOOST::is\u same))

它通过使用另一层括号来工作,从而形成一个
元组
(从宏观角度看)

如果使用该库,可以轻松地“展开”元组,使其内容不受损坏。不幸的是,您应该预先知道元组的大小,因此需要一个额外的参数

#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";
myu宏(2,(std::map),idToName);
//扩展为“std::map idToName”
idToName[1]=“史密斯”;

因此,是的,这是可能的,但宏必须显式地定制以处理它。

是的,只要您可以安排它,使
std::map
成为您的最终或唯一参数。只需使用
\uu VA\u ARGS\uu
,例如:

#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 MAKE_A_NEW_其中一个(A,…)\u VA_ARGS\u*A=NEW_VA_ARGS__
使这些(pMyMap,std::map)中的一个成为新的;

我想他们第一次听到你说的……应该是C吗?还是C++?只是好奇,我们能看到问题的宏观吗?也许有更好的方法来完成你用它做的任何任务。
@AndreyT
:因为他用的是
地图
,我想说
C++
。。。不是吗?
typedef
克服了嵌套宏的问题,但更持久。我支持
typedef
方法。只要有一个替代品不涉及宏,并提供相同的易用性。。。你最好不用宏。哦,太酷了。如果可以,我会给你+10。非常感谢。
第2项
在这里不适用:它没有提到模板,只是常量。。。虽然我同意大家的看法,但如果一切都有可能的话。。那太好了。这是第2项的内联线。我在这里提到了模板,因为宏不关心类型,所以通常不能用普通函数替换它们。但是使用模板可以让你做到这一点。我认为Meyer对模板使用了min/max宏来演示。不要在宏定义中用括号括住
args
,它已经带有括号了。如果有人使用singluar参数,则在使用宏时可以省略parenthasis,这就是为什么args是parenthasis,其余时间是不做任何事情,超级妄想症被删除/忽略括号似乎没有被忽略。第一个示例扩展为
(std::map)map
根本无法编译(在未声明的标识符映射上强制转换为C样式)。似乎第一个exmaple没有成功(parenthasis仅在
DEF
宏中被忽略),感谢您指出它,用“正确”的解决方案修复它。如果您正在进行一些预处理编程,有一些方法。不过,这可能会给用户带来一些负担,这取决于您所追求的,而且宏需要定制以处理它。。。请参阅我的答案。我还应该补充一点,这可能会很麻烦,因为用户需要计算
:/
#define _W(...) __VA_ARGS__
#define VAR(x,y) x y

VAR(_W(std::map<std::string, float>),Map);
#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 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>);