简体   繁体   中英

C++ how to #define/rename a nested function?

    namespace first {
    namespace second {
        class Third {
            static void foo() {
                std::cout << "foo\n";
            }
        };
    }
    }

    void bar() {
        std::cout << "bar\n";
    }

    #define first::second::Third::foo bar//this doesn't work

so, what's the correct way to map a nested function to another one?

Update:

a more similar situation is:

    struct ReleaseVersion {
        static void foo() {
            std::cout << "release version\n";
        }
    };

    struct DebugVersion {
        static void foo() {
            std::cout << "debug version\n";
        }
    };

    #ifdef _DEBUG 
    #define ReleaseVersion::foo DebugVersion::foo
    #else
    #define DebugVersion::foo ReleaseVersion::foo
    #endif

what I want to do is just like malloc and _malloc_dbg, when #define _CRTDBG_MAP_ALLOC, in debug mode, malloc will be mapped to _malloc_dbg, and in release mode, _malloc_dbg will be mapped to malloc

Update again

a more more similar situation is:

    namespace first {
    namespace second {
    struct ReleaseVersion {
        static void foo() {
            std::cout << "release version\n";
        }
    };

    struct DebugVersion {
        static void foo(const char* file, long line) {
            std::cout << "debug version\n";
        }
    };
    }
    }
    #ifdef _DEBUG 
    #define ReleaseVersion::foo() DebugVersion::foo(__FILE__, __LINE__)
    #else
    #define DebugVersion::foo(file, line) ReleaseVersion::foo()
    #endif

so, these 2 version of functions may have different parameters, I cannot just call one. I know I can just do this

    #ifdef _DEBUG 
    #define Foo() first::second::DebugVersion::foo(__FILE__, __LINE__)
    #else
    #define Foo() first::second::ReleaseVersion::foo()

but in this way, I must always use Foo(), even in the final release mode, it's still a macro. I want to know if there are more flexible way to to do this.

One Solution

    #ifdef _DEBUG 
    #define foo() foo(__FILE__, __LINE__)
    #define ReleaseVersion DebugVersion
    #else
    #define foo(file, line) foo()
    #define DebugVersion ReleaseVersion
    #endif


    int main() {
        first::second::DebugVersion::foo(__FILE__, __LINE__);
        first::second::ReleaseVersion::foo();
        return 0;
    }

it may be dangerous when there are another foo() or RealeaseVersion/DebugVersion in other namespaces, but if you can make sure there won't, I think it can be an acceptable solution.

Your #define is the wrong way around:

#define bar first::second::Third::foo

means that bar will be replaced by first::second::Third::foo , which, I believe, is what you want.

This is the opposite of typedef , where things are the other way around.

I'm not exactly sure what you want, but this works:

namespace first {
namespace second {
    class Third {
        public: static void foo() {
            std::cout << "foo\n";
        }
    };
}
}

#define bar first::second::Third::foo

int main()
{
  bar();
}

The way malloc / free works is by a macro replacement:

#ifdef WANT_DEBUG_MALLOC
#define malloc(x) debug_malloc(x, __FILE__, __LINE__)
#define free(x)   debug_free(x, __FILE__, __LINE__)
#endif

When the preprocessor sees struct foo *p = malloc(sizeof(struct foo) * 10); it will replace it with struct foo *p = debug_malloc(sizeof(struct foo) * 10, "myfile.c", 103);

However, as mentioned above, you can't really use namespaces when doing the macro replacement. You have to EITHER replace the namespace alone, or replace the function name alone. Of course, it's possible to have two macros, one to substitute the namespace, and one for substituting the function name. But it gets pretty messy pretty quickly, so best avoided, I'd say.

I would rather using inline functions

#ifdef _DEBUG 
static inline void DoFoo() { DebugVersion::foo(); }
#else
static inline void DoFoo() { ReleaseVersion::foo(); }
#endif

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM