C++ 微软 : How to associate uuid/guid with template specialization

标签 c++ templates com

我想将 uuid/guid 与模板特化相关联。

以下代码可用于将 uuid 与非模板接口(interface)(类、结构)相关联:

__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(...)) 添加到模板类定义中。这是显而易见的,因为接口(interface)的不同特化需要不同的 uuid。所以我尝试通过以下方式将 uuid 与模板特化相关联:

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

不幸的是,这也不起作用(__uuidof(.) 失败并显示“没有 GUID 与该对象相关联”)。

我的问题有什么解决方案吗?

这是在一些答案之后添加的更完整的示例:

假设我有一个适用于不同数据类型的复杂算法。为了简单起见,这种“复杂”的算法是对数字进行平方。我只想实现我的算法一次,所以模板是可行的方法。让我们进一步假设我想使用接口(interface),因为我的应用程序使用 COM。

所以这是一个接口(interface)和一个实现这个接口(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; };
    };

这允许做类似的事情

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::SquandAddOne 想要使用 CTemplateImplementation 特化的 __uuid 时,问题就出现了。尝试以下操作:

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

这不再有效,因为没有与 m_multiplier 关联的 GUID。那么如何在不复制代码的情况下将 guid 分配给 CTemplateImplementation 的不同实现(在本例中为三个)?你能提供一个完整的解决方案吗? 不可能从 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 分配给它。

关于C++ 微软 : How to associate uuid/guid with template specialization,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11966892/

相关文章:

C++ << 在队列模板中重载

c++ - 为什么 libxml2 在元素名称上输出 "text"(当它不是 "text"时)?

c++ - 关于模板特化和由此产生的代码重复的问题

c# - 通过 COM 将 DataTable 传递到 R

c++ - 变量似乎在自行改变值(value)

C++:std "magically"在那里吗?总是?

python - Django,在模板中创建变量并赋值

c++ - C++14 中的模板化函数参数

c++ - Internet Explorer 内容插件中的可编写脚本的对象

com - 是否有列出从 DLL 导出的方法的工具?