2016-02-05 58 views
0

我有一個類需要使用std ::隊列作爲實例var來存儲一些數據。我的問題是,std ::隊列默認使用std :: deque作爲容器類型,或者需要在編譯時提供另一個容器類型。但是,我想使用哪個容器取決於類用戶的一些運行時數據,因此我無法在編譯時指定它。在實例化std :: queue並提供適當的容器實現之後,我不再關心容器本身,而只使用std :: queue的接口。std ::隊列與不同的容器類型取決於運行時數據

我想提供的容器是std :: deque或boost :: circular_buffer,它們都存儲相同類型的元素,只有當調用者希望存儲無限量的數據時才使用它, _buffer如果不是。

到目前爲止我發現的唯一方法是一個自定義抽象基類,作爲不同std :: queue實例的兩個派生實現的通用接口。但在這種情況下,我不得不復制std :: queue的接口,這真的很煩人。

是否有任何方式來聲明和instanciate一個std ::隊列在這種方式?像「std ::隊列與未知/運行時提供的容器」。

回答

1

模板參數必須在編譯類型中已知。您將無法在運行時更改queue的基礎容器。你可以做的是某種包裝或聯合,它們將兩種類型的隊列結合在一起,然後根據運行時間條件在運行時使用其中一種或另一種。

1

如果你不希望有很多該類的實例則非常低技術,簡單的,但最終工作的方法是根本就是兩個不同的成員變量添加到您的類:一std::queue<T>一個std::queue<T, boost::circular_buffer<T>>。然後在實例化類時,在運行時選擇適當的容器。

這將花費您每個類的每個實例幾個額外的字節,因爲每個實例中都會有一個未使用的空容器,但同時也可以免除您在工會中遇到的任何困難或過於複雜的代碼, boost::variantvoid*或類似的東西。

下面是一個完整的例子:

#include <boost/circular_buffer.hpp> 
#include <queue> 
#include <deque> 
#include <iostream> 

class YourClass 
{ 
public: 
    YourClass(bool needs_infinite_amount_of_data) : 
     needs_infinite_amount_of_data(needs_infinite_amount_of_data), 
     queue(), 
     queue_with_circular_buffer(boost::circular_buffer<int>(needs_infinite_amount_of_data ? 0 : 100)) 
    { 
    } 

    void Operation() 
    { 
     if (needs_infinite_amount_of_data) 
     { 
      Operation(queue); 
     } 
     else 
     { 
      Operation(queue_with_circular_buffer); 
     } 
    } 

private: 
    template <class Container> 
    static void Operation(Container& container) 
    { 
     container.push(1); 
     std::cout << container.front() << "\n"; 
    } 

    bool needs_infinite_amount_of_data; 
    std::queue<int> queue; 
    std::queue<int, boost::circular_buffer<int>> queue_with_circular_buffer; 
}; 

int main() 
{ 
    YourClass obj(false); 
    obj.Operation(); 
} 
+0

我想的東西圍繞着自己,但並不意味着我需要一個包裝檢查容器使用每個方法我訪問容器在?就像你的兩個操作方法一樣...我沒有使用模板工作得到類似Container&getContainer()的東西。 –

+0

@ThorstenSchöning:是的,你需要包裝。但是你需要它在任何情況下。它可能在形式或語法上有所不同,但是沒有辦法繞過每個成員函數都必須對使用哪個容器做出運行時決定的事實。 –

+0

沒錯,但我更喜歡用重複的std :: queue接口創建我自己的小抽象類,並提供它的兩個具體實現,我的使用類的CTOR可以在它們之間進行選擇。這樣我只有一個地方需要記住創建正確的std :: queue實例,而其他方法正在對我的抽象類進行操作。所有這些「如果......其他」都是我試圖避免的。 –

相關問題