我需要#undef本地#define吗?是否存在本地定义?

Sam*_*rsa 14 c++ c-preprocessor

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

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

我不确定#define在这种情况下是如何工作的.现在,我当然已经尝试了代码并得出了一些结论,但由于我不确定,我想要一些专家意见/建议.

In *_*ico 26

#define不尊重任何C++范围.没有"本地"这样的东西#define.它会在#undef-ed 之前生效.预处理器的宏机制就像大多数文本编辑器中的"查找和替换"功能一样; 它不尊重文件的内容.

换句话说,如果您希望自己#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();
}
Run Code Online (Sandbox Code Playgroud)

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

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

    rlin::Foo f;
    rlin::Bar();
}
Run Code Online (Sandbox Code Playgroud)

你也可以使用typedefs:

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

    MyFoo f;
}
Run Code Online (Sandbox Code Playgroud)

您还可以使用using声明:

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

    Foo f;
    Bar();
}
Run Code Online (Sandbox Code Playgroud)

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

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

    MyFoo f;
    Bar();
}
Run Code Online (Sandbox Code Playgroud)

关于Ogre::Real,它似乎是typedefa float或a double.你仍然可以使用命名空间别名,typedefs和s using声明typedef:

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;
}
Run Code Online (Sandbox Code Playgroud)