[英]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.