c++ - 我需要#undef 本地#define 吗?有本地定义这样的东西吗?

标签 c++ c-preprocessor

有时为了使事情更易于编写和阅读,我在函数 中编写了一些本地 #define 宏(例如,#define O_REAL Ogre::Real)

我是否需要#undef 本地 #define 以确保它保持在某个代码块内?或者当它超出范围时它会自动#undef?它甚至有范围的概念吗?

我不确定 #define 在这种情况下是如何工作的。现在,我当然已经对代码进行了实验并得出了某些结论,但由于我不确定,我希望得到一些专家的意见/建议。

最佳答案

#define 不尊重任何 C++ 范围。没有“本地”#define 这样的东西。它将一直有效,直到它被 #undef 编辑。预处理器的宏机制就像大多数文本编辑器中的“查找和替换”功能一样;它不尊重文件的内容。

换句话说,如果您希望您的 #define 在某个代码块中是本地的,则必须在该代码块的末尾 #undef 它,因为宏不“理解”范围的事实。

事实上,这是不鼓励使用宏的最大原因之一,除非它们在 C++ 中是绝对必要的。这就是为什么通常在 UPPER_CASE 中键入宏名称以表明它实际上是一个宏。


实际上有很多针对您的具体情况的无宏解决方案。考虑以下几点:

namespace ReallyLongOuterNamespace
{
    namespace ReallyLongInnerNamespace
    {
        class Foo {};
        void Bar() {}
    };
}

void DoThis()
{
    // Too much typing!
    ReallyLongOuterNamespace::ReallyLongInnerNamespace::Foo f;
    ReallyLongOuterNamespace::ReallyLongInnerNamespace::Bar();
}

您可以使用命名空间别名:

void DoThis()
{
    namespace rlin = ReallyLongOuterNamespace::ReallyLongInnerNamespace;

    rlin::Foo f;
    rlin::Bar();
}

你也可以使用 typedefs:

void DoThis()
{
    typedef ReallyLongOuterNamespace::ReallyLongInnerNamespace::Foo MyFoo;

    MyFoo f;
}

你也可以使用 using 声明:

void DoThis()
{
    using ReallyLongOuterNamespace::ReallyLongInnerNamespace::Foo;
    using ReallyLongOuterNamespace::ReallyLongInnerNamespace::Bar;

    Foo f;
    Bar();
}

你甚至可以使用以上的组合!

void DoThis()
{
    namespace rlin = ReallyLongOuterNamespace::ReallyLongInnerNamespace;
    typedef rlin::Foo MyFoo;
    using rlin::Bar;

    MyFoo f;
    Bar();
}

对于 Ogre::Real,它似乎是 typedef 用于 floatdouble。您仍然可以使用命名空间别名、typedefs 和 using 声明以及 typedefs:

void UseOgre()
{
    typedef Ogre::Real o_Real; // Yes, you can typedef typedefs.
    using Ogre::Real;
    /* Or, you can use:
    namespace o = Ogre;
    typedef o::Real o_Real;
    using o::Real;
    */

    // All equivalent
    Ogre::Real r1;
    o_Real r2;
    Real r3;
    o::Real r4;
}

关于c++ - 我需要#undef 本地#define 吗?有本地定义这样的东西吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5056117/

相关文章:

c++ - 为什么字符数组不给出无符号结果

c++ - 使用复制构造函数后 SDL 纹理不渲染

c++ - lambda 中使用的静态变量未初始化

c++ - Lib 文件和定义

c++ - _GLIBCXX_VISIBILITY 是什么?

c++ - 如何识别 X 的最接近值倍数?

c - 一起使用 '#' 和 '##' 预处理运算符

concatenation - 使用 C 预处理器连接以指数表示法获取数字

c++ - #define 上的 gcc 4.9 错误

具有多个语句的 C++ 宏