繁体   English   中英

不能在 C++ 构造函数中使用宏?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM