簡體   English   中英

C ++ Microsoft:如何將uuid / guid與模板特化相關聯

[英]C++ Microsoft: How to associate uuid/guid with template specialization

我想將uuid / guid與模板專業化相關聯。

以下代碼可用於將uuid與非模板接口(class,struct)相關聯:

__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(...))添加到模板類定義中。 這是顯而易見的,因為界面的不同特化需要不同的uuids。 所以我嘗試通過以下方式將uuid與模板特化相關聯:

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

不幸的是,這也不起作用(__uuidof(。)失敗,“沒有GUID與此對象相關聯”)。

我的問題有什么解決方案嗎?

以下是一些更完整的示例,經過一些答案后添加:

假設我有一個適用於不同數據類型的復雜算法。 為簡單起見,這種“復雜”算法正在對數字進行平方。 我只想實現我的算法一次,所以模板是要走的路。 讓我們進一步假設我想使用接口,因為我的應用程序使用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 :: SquandAndAddOne想要使用CTemplateImplementation專門化的__uuid時,問題就出現了。 請嘗試以下方法:

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

這不再起作用,因為沒有與m_multiplier相關的GUID。 那么如何在沒有重復代碼的情況下為這些(在這種情況下為三個)CTemplateImplementation的不同實現分配guid? 你能提供完整的解決方案嗎? 從CTemplateImplementation為不同類型派生不同的類是不可能的,因為CSquareAndAddOne中正確類型化的專業化的使用不能再用模板參數控制。

我嘗試了一些明確的實例化魔法,它運行正常(至少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分配給類專門化。

嘗試:

__interface __declspec(uuid("CF4AB938-8CE0-4AB7-A56C-0253B6018C26")) 
ITestFloat: ITemplateTest<float> {
    virtual void Test() = 0;
};

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM