[英]Cannot use Macro in a C++ constructor?
我有一个复杂的类,我试图用宏来简化它。 宏在某些编译器上可以正常工作,但在其他编译器上则不行。 我在想宏只是文本替换,我错了吗?
struct FooManager
{
FooManager(){}
void Add( Foo* i_pFoo ){ m_FooObjects.Add( i_pFoo ); }
private:
DynamicArray<Foo*> m_FooObjects;
};
struct Foo
{
Foo( FooManager& mgr, int param1, int param2 = 0 )
: m_Param1( param1 )
, m_Param2( param2 )
{
mgr.Add( this );
}
private:
const int m_Param1, m_Param2;
}
class Bar
{
FooManager m_Manager;
Foo m_Foo1, m_Foo2;
public:
Bar();
};
然后在 .cpp 文件中...
#define Macro( f, a, ... ) f( m_Manager, a, __VA_ARGS__ )
Bar::Bar()
: m_Manager()
, Macro( m_Foo1, 1 )
, Macro( m_Foo2, 2, 3 )
{}
使用 gcc 编译器时出现“错误 29:预期的表达式”。
我真正想要的是我的酒吧有一个经理,他知道里面所有的 Foo。 我可以展开宏,但希望我不必这样做,因为它使事情看起来更清晰,并且它可以根据使用情况提供其他共享参数。
我倾向于相信我这样做违反了一条规则,并且它确实使用的编译器出于某种原因忽略了这条规则。
在__VA_ARGS__
为空的情况下(例如,当扩展Macro( m_Foo1, 1 )
),您的宏将在构造函数初始值设定项列表中生成以下条目
m_Manager(<some argument>, )
这显然是无效的。 __VA_ARGS__
的想法是您应该为__VA_ARGS__
部分提供至少一个参数。
为了使__VA_ARGS__
在这种情况下更容易使用,众所周知,像 MSVC 这样的编译器在这种情况下会实现非标准行为:它们悄悄地删除过多的逗号,使您的原始代码按预期进行编译。
GCC 还实现了一个非标准的扩展,用于相同的目的,但你必须通过使用##
的非标准技巧来激活它
#define Macro( f, a, ... ) f( m_Manager, a, ##__VA_ARGS__ )
当__VA_ARGS__
为空时,这将自动删除 GCC 中的尾随逗号。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.