C ++ Microsoft:如何将uuid / guid与模板专门化相关联 [英] C++ Microsoft: How to associate uuid/guid with template specialization

查看:168
本文介绍了C ++ Microsoft:如何将uuid / guid与模板专门化相关联的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想将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与模板专业化关联:

 模板< __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);
}

这不再工作,因为没有GUID与m_multiplier 。那么如何在不重复代码的情况下为CTemplateImplementation的不同实现分配GUID(在这种情况下为三个)?你能提供一个完整的解决方案吗?
不可能从不同类型的CTemplateImplementation派生不同的类,因为在CSquareAndAddOne中使用正确类型的专门化不能用模板参数控制。

解决方案

我试过一些明显的实例化魔法,它的工作原理(至少VS2008 SP1):

  template< class T> __interface ITemplateTest {void Test(T t); }; //接口声明

template __interface ITemplateTest< float> ;; //显式实例化

template __interface __declspec(uuid(CF4AB938-8CE0-4AB7-A56C-0253B6018C26)ITemplateTest< float> ;; //使用uuid关联重复显式实例化

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

最初的问题是 __ declspec 试图在实际实例化之前将guid指定给类特殊化


I'd like to associate a uuid/guid with a template specialization.

The following code can be used to associate a uuid with a non-template interface (class, struct):

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

GUID guid = __uuidof(ITest);   // OK

Now I have a templated interface

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

and I'd like to make the following work:

GUID templateGuid = __uuidof(ITemplateTest<float>);

It is not possible to add the __declspec(uuid(...)) to the template class definition. This is obvious, since different specializations of the interface need different uuids. So I tried to associate the uuid with a template specialization in the following way:

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

Unfortunately, this doesn't work either (__uuidof(.) fails with "no GUID has been associated with this object").

Is there any solution to my problem?

Here is a more complete example added later after some answers:

Let's say I have a complex algorithm that works on different data types. This "complex" algorithm is squaring a number for the sake of simplicity. I'd like to implement my algorithm only once, so templates is the way to go. Let's further assume that I want to use interfaces, because my app makes use of COM.

So here is an interface and a templated object that implements this interface:

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; };
    };

This allows to do something like

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;

Now let's further assume that I have another template object, also implementing a very "complex" algorithm, that makes use of CTemplateImplementation:

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

This object can now be used in the same way:

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;

The problem arises, when CSquareAndAddOne::SquandAndAddOne wants to make use of the __uuid of a CTemplateImplementation specialization. Try the following:

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

This doesn't work any more, because there is no GUID assiciated with m_multiplier. So how can I assign guids to the (three in this case) different implementations of CTemplateImplementation without duplicating code? Can you provide a complete solution? Deriving different classes from CTemplateImplementation for different types is not possible, since usage of the correctly typed specialization in CSquareAndAddOne can not be controlled with a template argument any more.

解决方案

I tried some explicit instantiation magic and it works OK (at least with 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! :-)

Looks like initial problem was that __declspec tried to assign guid to class specialization before it was actually instantiated.

这篇关于C ++ Microsoft:如何将uuid / guid与模板专门化相关联的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆