不能在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的经理。我可以打开Macro,但希望我不必这样做,因为它让东西看起来更干净,而且它可以根据使用情况提供其他共享参数。
我倾向于相信,我这样做违反了一条规则,而与之合作的编译器出于某种原因忽视了这条规则。
在__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中的尾随逗号。
相关文章:
- "error: no matching function for call to"构造函数错误
- C++17复制构造函数,在std::unordereded_map上进行深度复制
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- 为什么在没有显式默认构造函数的情况下,将另一个结构封装在联合中作为成员的结构不能编译
- 为什么在C++中使用私有复制构造函数与删除复制构造函数
- 选择要调用的构造函数
- 如何委托派生类使用其父构造函数?
- 构造函数正在调用一个使用当前类类型的函数
- 没有用于初始化C++中的变量模板的匹配构造函数
- 初始化具有非默认构造函数的std::数组项的更好方法
- 当从函数参数中的临时值调用复制构造函数时
- 在c++构造函数中使用随机字符串生成器
- 一对向量构造函数:初始值设定项列表与显式构造
- 从构造函数抛出异常时如何克服内存泄漏
- 我不明白为什么我声明一个空的内部结构并将其传递给构造函数
- 继承:构造函数,初始化C++11中基类的类C数组成员
- 具有默认模板类型的默认构造函数的类型推导
- 使用dynamic_cast和构造函数时出错
- 在c++中使用向量时,如何调用构造函数和析构函数
- 奇怪的构造函数行为