5

Type Erasure を使用して、任意の型をカプセル化するオブジェクトを作成し (それを と呼びましょうErasedType)、実行時にクエリを実行して、別の任意の型Tが に変換可能かどうかを確認できますErasedTypeか?

考えてみると、理論上は可能かもしれませんが、可能ではないと思います。コンパイラはT、比較しようとしている型を認識しているErasedTypeため、実行前に必要なコードを生成できます。問題は、実際には、基本クラスのインスタンスからサブクラスのインスタンスにテンプレート パラメーターの型を渡す方法ないように見えることです。

例えば:

struct FooBase
{
    template <class TestType>
    bool is_convertible()
    {
        return call_derived();
    }

    protected:

    virtual bool call_derived() = 0;

    template <class ErasedType>
    void base_class_function() { }
};

template <class ErasedType>
struct Foo : public FooBase
{
    bool call_derived()
    {
        // Here we have access to the ErasedType but no access to TestType.
            //
        // We could pass ErasedType to a base class function by saying:
        //
        // this->base_class_function<ErasedType>();
        //
        // ...but that doesn't seem to help since we still don't have access to
        // TestType
    }
};



したがって、目標は次のようなことを言えるようになることです。

FooBase* f = new Foo<int>();
bool res1 = f->is_convertible<double>(); // returns true
bool res2 = f->is_convertible<long>(); // returns true
bool res3 = f->is_convertible<std::string>(); // returns false

しかし、同じ関数内で makeとaccess を一緒に行う方法がないため、FooBase::is_convertibleメソッドを実装する方法がわかりません。したがって、コンパイラは次の結果を計算できます。TestTypeErasedTypestd::is_convertible<TestType, ErasedType>::value

それで、これはまったく可能ですか?

4

1 に答える 1

2

一般に、C++では実際には不可能です。実行時に型に関する任意のクエリを作成するには、かなりの量のメタデータが必要であり、C++ はこれを最小限に抑えようとします (少し煩わしい場合もあります。機能は「使用時に」自動的にオプトインされる可能性があるため、不必要なオーバーヘッドはありませんが、私は脱線します)。

David がほのめかしているように、コンパイラの情報をある程度まで複製することは完全に可能ですが、完全に自動的に複製することはできません。これにより、実行時の型情報が手動で追加するものに制限されます。

このメタデータを提供するために、C++ の上にフレームワーク全体があるQtのようなライブラリを見て、どのような作業が関係しているかを確認してください。目の前の問題によっては、それなしでやっていけることもあります。

于 2012-08-10T19:06:03.320 に答える