0
    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_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

したがって、これらの2つのバージョンの関数は異なるパラメーターを持っている可能性があり、1つだけを呼び出すことはできません。私はこれができることを知っています

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

しかし、このように、私は常にFoo()を使用する必要があります。最終リリースモードでも、それはまだマクロです。これを行うためのより柔軟な方法があるかどうか知りたいです。

1つの解決策

    #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がある場合は危険かもしれませんが、ないことを確認できれば、許容できる解決策になると思います。

4

3 に答える 3

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();
}
于 2013-02-20T11:09:44.050 に答える
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つのマクロを使用することもできます。1つは名前空間を置き換えるためのもので、もう1つは関数名を置き換えるためのものです。しかし、それはかなりすぐにかなり乱雑になるので、避けるのが最善だと思います。

于 2013-02-20T12:18:23.677 に答える
0

インライン関数を使用したい

#ifdef _DEBUG 
static inline void DoFoo() { DebugVersion::foo(); }
#else
static inline void DoFoo() { ReleaseVersion::foo(); }
#endif
于 2013-02-20T12:31:32.573 に答える