Sometimes to make things easier to write and read, I write some local #define macros within functions (for example, #define O_REAL Ogre::Real)
.
#define
does not respect any C++ scope. There is no such thing as a "local" #define
. It'll be in effect until it is #undef
-ed. The preprocessor's macro mechanism is just like the "find-and-replace" functionality found in most text editors; it has no respect for the contents of the file.
In other words, if you want your #define
to be local within a certain block of code, you must #undef
it at the end of that block due to the fact that macros do not "understand" scope.
In fact, that's one of the biggest reasons why macros are discouraged unless they are absolutely necessary in C++. It's why macro names are usually typed in UPPER_CASE
to indicate that it's in fact a macro.
There are actually quite a few macro-less solutions for your specific situation. Consider the following:
namespace ReallyLongOuterNamespace
{
namespace ReallyLongInnerNamespace
{
class Foo {};
void Bar() {}
};
}
void DoThis()
{
// Too much typing!
ReallyLongOuterNamespace::ReallyLongInnerNamespace::Foo f;
ReallyLongOuterNamespace::ReallyLongInnerNamespace::Bar();
}
You can use namespace aliases:
void DoThis()
{
namespace rlin = ReallyLongOuterNamespace::ReallyLongInnerNamespace;
rlin::Foo f;
rlin::Bar();
}
You can also use typedef
s:
void DoThis()
{
typedef ReallyLongOuterNamespace::ReallyLongInnerNamespace::Foo MyFoo;
MyFoo f;
}
You can also use using
declarations:
void DoThis()
{
using ReallyLongOuterNamespace::ReallyLongInnerNamespace::Foo;
using ReallyLongOuterNamespace::ReallyLongInnerNamespace::Bar;
Foo f;
Bar();
}
You can even use a combination of the above!
void DoThis()
{
namespace rlin = ReallyLongOuterNamespace::ReallyLongInnerNamespace;
typedef rlin::Foo MyFoo;
using rlin::Bar;
MyFoo f;
Bar();
}
With respect to Ogre::Real
, it appears to be a typedef
for a float
or a double
. You can still use namespace aliases, typedef
s and using
declarations with typedef
s as well:
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;
}