C ++如何#define / rename一个嵌套函数?

时间:2013-02-20 11:00:36

标签: c++ macros

    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

那么,将嵌套函数映射到另一个函数的正确方法是什么?

更新

更类似的情况是:

    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

我想要做的就像malloc和_malloc_dbg,当#define _CRTDBG_MAP_ALLOC,在调试模式下,malloc将映射到_malloc_dbg,而在发布模式下,_malloc_dbg将映射到malloc

再次更新

更类似的情况是:

    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

所以,这两个版本的函数可能有不同的参数,我不能只调用一个。 我知道我可以这样做

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

但是这样,我必须总是使用Foo(),即使在最终发布模式下,它仍然是一个宏。 我想知道是否有更灵活的方法来做到这一点。

一种解决方案

    #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;
    }

当其他名称空间中有另一个foo()或RealeaseVersion / DebugVersion时,它可能很危险, 但如果你能确保没有,我认为这是一个可以接受的解决方案。

3 个答案:

答案 0 :(得分:2)

你的#define是错误的方式:

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

表示bar将被first::second::Third::foo取代,我相信这是您想要的。

这与typedef相反,事实恰恰相反。

我不确定你想要什么,但这有效:

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

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

int main()
{
  bar();
}

答案 1 :(得分:1)

malloc / free的工作方式是宏替换:

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

当预处理器看到struct foo *p = malloc(sizeof(struct foo) * 10);时,它会将其替换为struct foo *p = debug_malloc(sizeof(struct foo) * 10, "myfile.c", 103);

但是,如上所述,在进行宏替换时,您无法真正使用命名空间。您必须单独替换命名空间,或单独替换函数名称。当然,可以有两个宏,一个用于替换命名空间,另一个用于替换函数名。但它很快就变得非常混乱,所以最好避免,我会说。

答案 2 :(得分:0)

我宁愿使用内联函数

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