2

継承によって定義されたC++クラス階層があり、この階層の説明を格納して、後でイントロスペクションに使用できるようにします。私が現在行っている方法よりも、これを定義するためのより効率的またはよりクリーンな方法があるかどうかを知りたいです。これが私のコードの簡略版です

// in header file (hpp)
struct Type
{
    Type( const string& n, const Type* p = nullptr ) : name(n), parent(p) {}
    const string name;
    const Type* parent;
};

class Base
{
public:
    static const Type m_type;
    virtual const Type& type() const { return m_type; } 
};

class Derived : public Base
{
public:
    static const Type m_type;
    const Type& type() const { return m_type; }
};

// in implementation file (cpp)
const Type Base::m_type( "Base" );
const Type Derived::m_type( "Derived", &Base::m_type );
4

1 に答える 1

2

必ずしもより効率的ではありませんが、実際に共通の基本クラスを必要とするかどうかを考えてください。別のアプローチでは、グローバル型情報レジストリを使用します。次に、型の型情報のクエリは、TypeInfo::get(my_variable)またはを介して行われTypeInfo::get(typeid(my_type))ます。

これには、この型情報レジストリに追加するだけでよい既存の型でも機能するという利点があります。

内部的には、レジストリはstd::type_infotoTypeなどのマップを使用します。以下は概念実証です。残念ながら、コードは clang でも GCC でもコンパイルできません。エラー メッセージに基づいて、私はバグを疑っていますが、間違っている可能性もあります …</p>

struct Type {
    std::string name;
    std::vector<Type*> parents;
    // TODO Extend by fully-qualified name (namespace) etc.

    template <typename... T>
    Type(std::string&& name, T*... parents)
        : name(name), parents{parents...} { }
};

struct TypeInfo {
    template <typename T>
    static Type const& get(T const&) { return get(typeid(T)); }

    template <typename T>
    static Type const& get() { return get(typeid(T)); }

    static Type const& get(std::type_info const& info) {
        auto i = types.find(info);
        if (i == types.end())
            throw unknown_type_error(info.name());

        return i->second;
    }

    template <typename T>
    static void register_type(Type&& type) {
        types.insert(std::make_pair(typeid(T), type));
    }

    typedef std::unordered_map<std::type_info, Type> type_dir_t;
    static type_dir_t types;
};

完全なコードは github の gist として入手できます。

論理的に関連のないクラスに共通の基本クラスを持つことは、C++ では一般的に嫌われていますが、これは共通の基本クラス奨励されている CRTP / mixin に似ていると主張することもできます。したがって、既存の型を気にしないのであれば、このアプローチに必ずしも問題があるとは言えません。

于 2012-05-16T13:10:33.370 に答える