4

uuid/guid をテンプレートの特殊化に関連付けたいと思います。

次のコードを使用して、uuid を非テンプレート インターフェイス (クラス、構造体) に関連付けることができます。

__interface __declspec(uuid("CECA446F-2BE6-4AAC-A117-E395F27DF1F8")) ITest {
    virtual void Test() = 0;
};

GUID guid = __uuidof(ITest);   // OK

今、私はテンプレート化されたインターフェースを持っています

template<class T> __interface ITemplateTest {
    virtual void Test(T t) = 0;
    };

そして、私は次の仕事をしたいと思います:

GUID templateGuid = __uuidof(ITemplateTest<float>);

テンプレート クラス定義に __declspec(uuid(...)) を追加することはできません。インターフェースの異なる特殊化には異なる uuid が必要なので、これは明らかです。そこで、次の方法で uuid をテンプレートの特殊化に関連付けようとしました。

template<> __interface __declspec(uuid("CF4AB938-8CE0-4AB7-A56C-0253B6018C26")) ITemplateTest<float>;

残念ながら、これも機能しません (__uuidof(.) は「このオブジェクトに関連付けられた GUID がありません」で失敗します)。

私の問題の解決策はありますか?

いくつかの回答の後に後で追加されたより完全な例を次に示します。

さまざまなデータ型で機能する複雑なアルゴリズムがあるとします。この「複雑な」アルゴリズムは、簡単にするために数値を 2 乗しています。アルゴリズムを一度だけ実装したいので、テンプレートが最適です。さらに、アプリで COM を使用するため、インターフェイスを使用するとします。

インターフェースと、このインターフェースを実装するテンプレート化されたオブジェクトを次に示します。

template<class T> __interface ITemplateTest {
    virtual T Square(T t) = 0;
    };

template<class T> class CTemplateImplementation : public ITemplateTest<T> {
    public:
        virtual T Square(T t) { return t * t; };
    };

これにより、次のようなことができます

CTemplateImplementation<double> xDouble;
CTemplateImplementation<float>  xFloat;
CTemplateImplementation<int>    xInt;

std::cout << xDouble.Square(5.) << std::endl
          << xFloat.Square(5.0f) << std::endl
          << xInt.Square(5) << std::endl;

さらに、CTemplateImplementation を利用する非常に「複雑な」アルゴリズムを実装する別のテンプレート オブジェクトがあるとします。

template<class T> class CSquareAndAddOne {
    private:
        CTemplateImplementation<T> m_squarer;
    public:
        T SquareAndAddOne(T t) { return m_squarer.Square(t) + T(1); }
    };

このオブジェクトは、同じ方法で使用できるようになりました。

CSquareAndAddOne<double> yDouble;
CSquareAndAddOne<float>  yFloat;
CSquareAndAddOne<int>    yInt;

std::cout << yDouble.SquareAndAddOne(5.) << std::endl
          << yFloat.SquareAndAddOne(5.0f) << std::endl
          << yInt.SquareAndAddOne(5) << std::endl;

CSquareAndAddOne::SquadAndAddOne が CTemplateImplementation 特殊化の __uuid を利用したい場合、問題が発生します。次のことを試してください。

    T SquareAndAddOne(T t) {
        GUID guid = __uuidof(m_multiplier);
        return m_squarer.Square(t) + T(1);
        }

m_multiplier に関連付けられた GUID がないため、これは機能しなくなりました。では、コードを複製せずに CTemplateImplementation の異なる実装 (この場合は 3 つ) に GUID を割り当てるにはどうすればよいでしょうか? 完全なソリューションを提供できますか? CSquareAndAddOne で正しく型指定された特殊化の使用をテンプレート引数で制御できないため、異なる型の CTemplateImplementation から異なるクラスを派生させることはできません。

4

2 に答える 2

3

明示的なインスタンス化の魔法をいくつか試してみましたが、問題なく動作します (少なくとも VS2008 SP1 では):

template<class T> __interface ITemplateTest { void Test(T t); }; // Interface declaration

template __interface ITemplateTest<float>; // Explicit instantiation

template __interface __declspec(uuid("CF4AB938-8CE0-4AB7-A56C-0253B6018C26") ITemplateTest<float>; // Repeat explicit instantiation with uuid association

GUID guid = __uuidof(ITemplateTest<float>); // Enjoy! :-)

最初の問題は、実際にインスタンス化される前__declspecにクラスの特殊化に guid を割り当てようとしたことだったようです。

于 2012-08-16T14:22:03.320 に答える
0

試す:

__interface __declspec(uuid("CF4AB938-8CE0-4AB7-A56C-0253B6018C26")) 
ITestFloat: ITemplateTest<float> {
    virtual void Test() = 0;
};
于 2012-08-15T11:40:36.353 に答える