将参数定义为未指定的模板类型

时间:2013-08-11 18:02:51

标签: c++ templates generics

我尝试创建一个SSCE,因为这通常也有助于在早期找到问题。但是,我似乎无法找到解决方案,所以我想知道是否可以定义一个未指定模板类指针的参数。

我有一个定义的接口和一个解析器类,它应该处理xerces的实现细节(比如转码和所有这些开销)。接口类将被设计为从(SAX)解析器创建对象,但不必处理xerces库。

在Java中我知道我可以使用这样的未指定的泛型类型参数:

class Parser
{
    public Parser(IGenericInterface<?> oImpl) {};
}

基本上我想知道在C ++中如何做到这一点。在下面的例子中,我在声明接口变量的行上遇到编译器错误,因为它缺少类型。但是当然在类声明中类型是未知的,应该在运行时分配,如main所示。

#include <iostream>
#include <string>

template <class T>
class IGenericInterface
{
public:
    IGenericInterface() {};
    virtual ~IGenericInterface() {};

    virtual T *createInstance(void) = 0;
};

template <class T>
class Implementation : public IGenericInterface<T>
{
public:
    Implementation() {};
    virtual ~Implementation() {};

    T *createInstance(void)
    {
        T * t = new T;
        return t;
    }
};

class Parser
{
public:
    Parser(IGenericInterface *oImpl) { mImpl = oImpl; };
    virtual ~Parser() { delete mImpl; };

    void doSomething(void) {  do whatrever is needed; t = createInstance(); };

private:
    IGenericInterface *mImpl;
};

int main()
{
    Parser *p = new Parser(new Implementation<int>());
    sleep(3);

    return 0;
}

那么如何定义Parser构造函数以使其传递任意接口参数?

3 个答案:

答案 0 :(得分:1)

混合静态和动态多态是不行(可能适用豁免)

template <class T>
class IGenericInterface
{
public:
    IGenericInterface() {};
    virtual ~IGenericInterface() {};

    virtual T *createInstance(void) = 0;
};

你使用指针是一场噩梦。

答案 1 :(得分:1)

C ++是一种静态语言,因此必须在编译时解析所有类型。因此,你在java中所做的事情在C ++中不能以相同的方式完成。相反,您使用动态多态(使用继承)或“静态多态”,使用模板(在编译时解析)与CRTP。

答案 2 :(得分:0)

由于Java中的泛型显然不能用C ++实现,我发现了一个不同的解决方案,它也允许我将解析器的细节分开。

现在应该在Interface类中的函数作为虚拟抽象函数移动到解析器类。我可以定义一个派生自解析器的模板,因此被迫实现虚拟函数,这基本上就是我想要的。

现在的模式如下:

template <class T>
class ISerialization
{
public:
    virtual ~ISerialization(void) {};

public:
    virtual std::string serialize(void) = 0;
    virtual bool deserialize(std::vector<T *> &oObjects, std::string const &oSerialized) = 0;
};

class parser
{
    void parsing(void) { abstract_function(); }
    virtual void abstract_function() = 0;
};


class implementation : public ISerialization<Task>, public parser
{
    std::string serialize(void) {};
    bool deserialize(std::vector<T *> &oObjects, std::string const &oSerialized) {};
    void abstract_function() { specific implementation goes here};
};