C ++微软:如何UUID /与模板特殊化关联的GUID(C++ Microsoft: How to

2019-09-21 05:25发布

我想一个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已与此对象相关联”)。

有没有解决我的问题?

下面是一些答案后,后来加了更完整的例子:

比方说,我有一个复杂的算法对不同数据类型的作品。 这个“复杂”的算法,用于平方简单起见一个数字。 我想实现我的算法只有一次,所以模板是要走的路。 让我们进一步假设,我想使用的接口,因为我的应用程序利用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 assiciated。 那么,如何分配(在这种情况下为三个)GUID来的CTemplateImplementation的不同实现,而不用复制代码? 你可以提供一个完整的解决方案? 从CTemplateImplementation派生不同类别的不同类型是不可能的,因为在CSquareAndAddOne的正确输入专业化的用法不能用模板参数更多的控制。

Answer 1:

我尝试了一些显式实例魔术和它的工作原理确定(与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类专业化然后才实际实例。



Answer 2:

尝试:

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


文章来源: C++ Microsoft: How to associate uuid/guid with template specialization