Any portable tricks to obtain namespace name in C++?

  • A+

I have some well-formed code looks like this:

NAMESPACE_BEGIN(Foo) inline void test() {     string s = xxx; } NAMESPACE_END(Foo) 

So, is there any portable tricks by using the NAMESPACE_BEGIN() macro to obtain namespace name "Foo" in test()?

I'm thinking of something like this, but it would surely cause symbol redefinition:

#define NAMESPACE_BEGIN(x) /     namespace x { /         inline const char *_curNamespace() { /             return #x; /         } #define NAMESPACE_END(x) /     } 

There's also a workaround looks like this, but that's not very convenient

#define NAMESPACE_NAME Foo // using a header file so that we can use #ifdef guard #include "MyNamespaceBegin.h" ... #include "MyNamespaceEnd.h" 


  • Why I need this:

    I'm using much of macro to generate codes to achieve some dynamic reflection logic (yes, not static template reflection), it's all right within class scope by using static member function, but does not work for namespaces

  • Why not to manually declare the name getter once:

    What I want is something like this:

    // the global default version const char *_curNamespace() {return "";}  namespace X {     // the local namespace version     const char *_curNamespace() {return "X";}      // some verbose reflection register code     ...     registerSomething(_curNamespace());     ... } 

    Of course, all of the verbose register code should be generated by macro

    And, app level user should not care about the _curNamespace(), so, I want to simplify the user's usage, by using a custom NAMESPACE_BEGIN(xxx) macro at any case

  • If you are still curious about what I'm doing, check this:

    I'm using lots of tricks to achieve fully dynamic reflection in pure C++, to achieve some of my fancy thoughts, for now, this project is just for fun, I have no idea whether it has practicability


For now, I think the best workaround should be like this:

#define NAMESPACE_BEGIN(ns) /     namespace ns { /         extern const char *__curNS(); #define NAMESPACE_END(ns) /     } #define NAMESPACE_REG(ns) /         const char *__curNS() {return #ns;} 
  • app level users still only need to care about NAMESPACE_BEGIN
  • NAMESPACE_REG must be declared exactly once, in source file
    • if not, undefined symbol would happen
    • if more than once, duplicated symbol would happen
    • although it's annoying and sometimes you need additional source file to hold the NAMESPACE_REG, the strict rule should prevent user from forgetting the ugly workaround


You are making much fuss over something that is trivial to implement.

First of all, use of NAMESPACE_BEGIN and NAMESPACE_END seems unnecessary to me. I don't see how that is more readable or useful than

namespace Foo { } 

If getting the name of the namespace is important/useful, add a trivial function.

namespace Foo {    inline std::string get_name() { return "Foo"; } } 

Small sized real world applications need thousands of lines of code. Large sized real world applications need millions of lines of code. From that perspective, implementing a one line inline function is a very minor task.


:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: