簡體   English   中英

具有編譯時已知參數的純虛擬成員函數?

[英]Pure Virtual member function with compile-time known parameter?

我正在通過嘗試為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;

如果有人可以給我一些建議,我將不勝感激。 預先感謝大家的幫助和時間。

typename關鍵字只能是模板聲明的一部分。

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

您已經混合了思維模板和純虛擬功能。 第一個是編譯時 ,第二個是運行時

模板允許您避免為不同的數據類型重復代碼,其中純虛擬成員函數允許您使用從同一類型繼承的不同多態接口。 類型擦除也與虛擬成員函數無關。 兩件事完全不同。

一旦使用例如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*

我不認為您真的想擁有一個帶有無限多個帶有不同參數的push和pop方法的接口。 我也不認為您想要概念后代的許多不同實現以及每種類型的單獨堆棧。 看來您想推送到不同類型的堆棧對象,然后彈出它們。 在這種情況下,可能是這樣的:

struct Container 
{
    template<typename T>
    Container(T t);
    template<typename U>
    U cast();
};

class Stack
{
public:
    virtual void push(Container val) = 0;
    virtual Container pop() = 0;
};

class ConcreteStack : public Stack
{
public:
    void push(Container val);
    Container pop();
};


int main() 
{
    ConcreteStack stack;
    stack.push(25);
    stack.push(std::string("abcd"));

    std::string str = stack.pop().cast<std::string>();
    int num = stack.pop().cast<int>();
}

不幸的是,在彈出時,我看不到逃脫顯式類型轉換的方法。 具有相同名稱的方法很少有,僅在返回類型上有所不同。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM