具有编译时已知参数的纯虚拟成员函数?

时间:2019-07-13 11:44:36

标签: c++ type-erasure pure-virtual

我正在通过尝试为STL容器实现一种类型擦除模式来练习,并且坚持使用那些容器的纯虚拟成员函数。我不知道如何实现充当接口的类型擦除模式的“概念”,其中包含擦除类型共享的纯虚拟成员函数。像Push这样的函数将需要一个编译时已知的参数。据我了解,虚拟函数不能使用自动或模板化,那么如何编写接口呢?

我尝试使用关键字'typename'告诉编译器该类型将在以后给出,但不会编译。

到目前为止,这是我对“概念”界面的了解:

class Concept{
public:
    virtual void push(typename T val) = 0;
    virtual typename T pop() = 0;
};

当前收到的错误是这样的:

error: expected nested-name-specifier before ‘T’ virtual void push(typename T val) = 0;
                              ^
error: expected ‘,’ or ‘...’ before ‘val’ virtual void push(typename T val) = 0;
                                ^~~
error: expected nested-name-specifier before ‘T’ virtual typename T pop() = 0;

如果有人可以给我一些建议,我将不胜感激。预先感谢大家的帮助和时间。

2 个答案:

答案 0 :(得分:0)

typename关键字只能是模板声明的一部分。

template <typename T> class Concept{
public:
    virtual void push(T val) = 0;
    virtual T pop() = 0;
};

您混合了思维模板和纯虚拟功能。第一个是编译时间,第二个是运行时间

模板使您可以避免针对不同数据类型重复编写代码,其中纯虚拟成员函数允许您使用从同一类型继承的不同多态接口。 Type erasure也与虚拟成员函数无关。两件事完全不同。

一旦上述模板用int实例化,则等于:

   class Concept{
    public:
        virtual void push(int val) = 0;
        virtual int pop() = 0;
    };

现在,此类是抽象;您无法实例化它,但可以继承:

class f1 : public Concept {
    public:
    virtual void push(int val) { ... define it }
    virtual int pop()  { ... define it}
};

class f2 : public Concept {
    public:
    virtual void push(int val) { ... define it }
    virtual int pop()  { ... define it}
    ... more members
};

并多态使用它:

Concept* a = new f1();
Concept* b = new f2();

// dynamic_cast<f1>(a) will return a f1*
// dynamic_cast<f2>(b) will return a f2*

答案 1 :(得分:0)

我不认为您真的想拥有一个带有无限多个带有不同参数的push和pop方法的接口。我也不认为您想要概念后代的许多不同实现以及每种类型的单独堆栈。 看来您想推送到不同类型的堆栈对象,然后弹出它们。在这种情况下,可能是这样的:

let oItems = oEvent.getParameter("selectedItems");
let oTable = this.getView().byId("myTable");
let oModel = new sap.ui.model.json.JSONModel();
oModel.setData(oItems);
oTable.setModel(oModel);

不幸的是,我看不到弹出时逃脱显式类型转换的方法。同名的方法很少有,只是返回类型有所不同。