1

maエンジンでタグエンティティを許可するタグシステムを作成しました。これは C++ 型に基づいて動作するため、すべてのタグが型です (理由があります)。

さて、新しいタグを作成したいときは、 を呼び出さなければなりませんstruct tagname{};

他のファイルでタグを使用したい場合は、前方宣言を使用しますstruct name;

より使いやすくするために、マクロを作成しました

#define CREATE_TAG(name) struct name{};
#define USE_TAG(name)    struct name;

しかし、ユーザーが名前空間内で 1 つのマクロを呼び出し、名前空間外で別のマクロを呼び出すと、問題が発生します。これは 2 つの異なるタイプであるためです。

ユーザーが名前空間の外でマクロを呼び出すことを確認したいと思います。私たちのプロジェクトは 1 つの名前空間namespace rootにあるため、チェックに使用できます。

これは私がこれまでに思いついたものです:

namespace root
{
    const unsigned TAGS_CAN_NOT_BE_DEFINED_INSIDE_ANY_NAMESPACE = 1;
};

#define CREATE_TAG(name)    namespace root{  struct name{}; static_assert(root::TAGS_CAN_NOT_BE_DEFINED_INSIDE_ANY_NAMESPACE,"");  }
#define USE_TAG(name)       namespace root{  struct name;   static_assert(root::TAGS_CAN_NOT_BE_DEFINED_INSIDE_ANY_NAMESPACE,"");  }

マクロがルート名前空間の外で使用される場合、すべて問題ありません。ルート名前空間または他のネストされた名前空間内で呼び出されると、エラーが発生しますTAGS_CAN_BE... not a member

しかし、私はそれがあまり好きではありません。私はマクロ全体が好きではありませんが、それは問題ではありません。質問: マクロが名前空間で呼び出されているかどうかを確認するより良い方法はありますか? 私のマクロは Type を渡すので、いくつかの typetraits を使用できますが、適切なものが見つかりませんでした。

4

2 に答える 2

0

あなたはこのようなことを試すことができます:

#include <type_traits>
#define DECLARE_ME(name) struct tag_##name { static_assert(!std::is_same<tag_##name, ::tag_##name>::value, "Not in global namespace"); }

誤用した場合の静的アサーションでもないコンパイラエラーが発生する可能性がありますが、問題は解決するはずです。より精巧なトレイトクラスを使用すると、おそらくよりユーザーフレンドリーにすることができます。

于 2012-05-20T10:12:20.573 に答える
0

だからそれは

namespace root
{
    const unsigned TAGS_CAN_NOT_BE_DEFINED_INSIDE_ANY_NAMESPACE = 1;
};

#define CREATE_TAG(name)    namespace root{  struct name{}; static_assert(root::TAGS_CAN_NOT_BE_DEFINED_INSIDE_ANY_NAMESPACE,"");  }
#define USE_TAG(name)       namespace root{  struct name;   static_assert(root::TAGS_CAN_NOT_BE_DEFINED_INSIDE_ANY_NAMESPACE,"");  }

答えです...

私はそれを受け入れる前に数日待ちます。私はまだあなたの答えを開いています

于 2012-05-21T10:18:53.943 に答える