C ++嵌套宏?

时间:2009-11-12 09:07:18

标签: c++ macros nested

在C ++中,有没有办法以类似于嵌套typedef的方式定义类中的嵌套宏/常量,或者实现类似功能的方法?动机通常是模板使用的宏。

class SomeClass
{
public:
    #define SomeConstant 123
};

int x=SomeClass::SomeConstant;

当然,静态const成员可以完成这项工作,但那些是物理变量,而我正在寻找一种简单的宏观行为。

7 个答案:

答案 0 :(得分:8)

你无法用宏做你想做的事。宏没有确定范围的概念。

但对于简单的int值,您可以使用枚举执行所需的操作。

class SomeClass
{
public:
    enum {
        SomeConstant=123
        };
};

int x=SomeClass::SomeConstant;

值的完全范围名称,但没有空间,即使在调试版本中 - 如果您愿意,也无法获取其地址。

答案 1 :(得分:6)

就地声明和定义的Const值正是您所需要的:编译器可以并且将完全优化它们,因此它们最终与首先使用#define完全相同,但具有以下优点:严格范围。

class SomeClass {
  public:
   static const int someValue = 10;
};

这不占用任何额外空间 - 没有分配内存来存储“someValue”。您可以证明这一点:如果您尝试使用“someValue”作为真实对象(即您尝试获取其地址),那么链接器会告诉您它未定义。

答案 2 :(得分:2)

宏完全忽略范围 - 它们在C ++编译之前被扩展。你不能这样做。

使用静态const通常会导致不分配变量 - 编译器将其视为常量。

答案 3 :(得分:1)

宏预处理器通常不了解语言上下文;因此,他们不知道“阶级”是什么让“在课堂上筑巢”一开始就没有意义。

对于你想要的,要么使用静态const,要么使用全名(假设预处理器允许使用宏名称中的冒号,而不是100%确定) - 虽然它不允许你继承派生类的常量:

#define SomeClass::SomeConstant 123

答案 4 :(得分:1)

您可以使用模板执行此操作:

template < int someConstant = 123 > class SomeClass
{
public:
    void outputConstant() { cout << "We think the answer is:" << someConstant; }
}

但这并不是你想要的,因为你必须将类的实例声明为:

int main(int argc, char *argv)
{
    SomeClass<123> myInstance;
}

我知道其他人已经解释了有关宏的问题,但允许我补充一点:#define由预处理器而不是编译器处理。在标准中有一个称为“翻译阶段”的部分,它更详细地解释了这一点,但是对于你的问题,重点是在编译类之前评估宏,并且不知道#define发生的范围。 / p>

关于这个主题的权威书籍(在编译阶段用模板编程)是Modern C++ Design: Generic Programming and Design Patterns Applied, by Andrei Alexandrescu

答案 5 :(得分:0)

我不明白你对使用静态const的反对意见。 它不会影响类的大小,编译器将进行优化以实现您从宏中获得的内容。

答案 6 :(得分:0)

“静态成员是物理变量”。

有什么反对的?反对这一点的唯一原因是内存使用。但由于成员是静态的,因此内存只会被预期的内容占用一次。

相反,使用宏,竞争将在二进制文件中的每个使用位置出现

编辑: 如果变量是整数类型,小于指针,则最好在类声明中定义常量。然后优化编译器可以内联调用代码中的值,就像宏一样。