2017-09-12 145 views
0

我有一個線程安全的隊列類像下面,C++類模板類型的std ::名單

類CMDQ:

template <typename Q> 
class CmdQ 
{ 
public: 
    CmdQ() : 
     queue_(), 
     queueMutex_(){}; 
    ~CmdQ() { 
     while (!queue_.empty()) { 
      Q* element(std::move(this->queue_.front())); 
      this->queue_.pop(); 
      delete element; 
     } 
    }; 
    void push(Q* commands) { 
     std::unique_lock<std::mutex> lock(this->queueMutex_); 

     queue_.push(commands); 
     this->mutexCondition_.notify_all(); 
    } 
    void pop() { 
     std::unique_lock<std::mutex> lock(this->queueMutex_); 
     while(this->queue_.empty())this->mutexCondition_.wait(lock); 
     Q* element(std::move(this->queue_.front())); 
     this->queue_.pop(); 
     delete element; 
    } 

    Q* front() { 
     std::unique_lock<std::mutex> lock(this->queueMutex_); 
     while(this->queue_.empty())this->mutexCondition_.wait(lock);  if (!queue_.empty()) { 
      return (queue_.front()); 
     } 
     return NULL; 
    } 

    bool empty() { 
     std::unique_lock<std::mutex> lock(this->queueMutex_); 
     return queue_.empty(); 
    } 

    void clear() { 
     std::unique_lock<std::mutex> lock(this->queueMutex_); 

     while (!queue_.empty()) { 
      Q* element(std::move(this->queue_.front())); 
      this->queue_.pop(); 
      delete element; 
     } 
    } 

    unsigned int size() { 
     std::unique_lock<std::mutex> lock(this->queueMutex_); 
     return queue_.size(); 
    } 

private: 
    std::queue queue_; 
    std::mutex queueMutex_; 
    std::condition_variable mutexCondition_; 
}; 

現在,我想這個隊列中包含列表。於是,我用如下:

ClassB.h:

template<typename std::list<Message*>> 
class CmdQ; 

CmdQ<std::list<Message*>>* msgListQ_; 

不過,我不斷收到錯誤,如:

錯誤1錯誤C2993:「的std ::名單< _Ty>」:非法類型用於非類型 模板參數‘__formal’

錯誤3錯誤C2975:‘CMDQ’:用於 無效模板參數‘未命名參數’,預期編譯添Ë常量表達式

我提到的一些文件該模板類型不能接受std::list,但會接受指針列表等也採用指針ClassB.h列出像下面的嘗試:

template<typename std::list<Message*>*> 
class CmdQ; 

CmdQ<std::list<Message*>*>* msgListQ_; 

但我仍然面臨錯誤。

任何幫助表示讚賞。

謝謝!

+2

不宜'的std ::隊列queue_;'是'的std ::隊列 queue_;'? – NathanOliver

+0

無論如何,你不需要顯式實例。你可以使用模板來聲明你的變量。 – chris

+0

@NathanOliver'的std ::隊列 queue',而 –

回答

2

我想錯部分是typename

template<typename std::list<Message*>*> 
class CmdQ; 

嘗試

template <std::list<Message*>*> 
class CmdQ; 

或避免它,簡單的寫

CmdQ<std::list<Message*>*>* msgListQ_; 

反正

我參考了一些文檔,說明模板類型不能接受std :: list

什麼?

模板類

template <typename> 
class foo { }; 

不接受std::list,如果你通過它沒有參數,如下

foo<std::list> fl0; 

(因爲std::list,通過這種方式,是一個模板,模板參數)但接受它與論據

foo<std::list<int>> fl1; 
+0

感謝您的建議。我改成了「template *> class CmdQ;」如所提到的,然後使用 「CMDQ <性病::列表 *> * msgListQ_;」。但是,我仍然看到與上面提到的相同的錯誤1和錯誤3。有關於此的任何其他見解? –

+0

@MonicaRajasekaran - 你試圖刪除和簡單的寫'CMDQ <性病::名單 *> * msgListQ_;'?無論如何,這個問題可能出現在標題包含的問題中。你有沒有在('CmdQ'實現的頭部之前)?你是否包含標準頭文件列表?我應該準備一個最小但完整的例子來重現錯誤。 – max66

+0

是的!這工作。萬分感謝。那個班級的前進宣言讓我感到困惑。 –

2

班是壞的(不編譯)因爲無效

std::queue queue_; 

聲明。 std::queue是一個模板,您需要提供有效的模板參數。

既然你推,Q*類型的流行的東西,用模板的其餘部分保持一致的唯一聲明將

std::queue<Q*> queue_; 

現在CmdQ<std::list<Message*>*>完全錯誤作爲內部隊列將存儲在堆上分配指向列表指針的指針(即存儲指針本身)。你當然不希望這樣。

這是一個糟糕的設計約束您的隊列類指針工作(並擁有尖銳的物體)雖然。嚴格限制選擇是沒有意義的。原始C風格的指針不推薦用於一般用途,智能指針應該是首選。移動指針也沒有意義。擁有一張清單,而不是它的要素也沒有意義。如果從類中刪除所有星號,並刪除調用delete,模板變得更簡單,更通用的,更一致。然後您可以使用

CmdQ<std::list<Message>> // store lists by value 
CmdQ<std::list<Message*>*> // store pointers to lists of pointers (not recommended) 
CmdQ<std::unique_ptr<std::list<std::shared_ptr<Message>>>> // etc 

或您喜歡的任何組合。您可能需要在這裏和那裏添加幾個電話到std::move。你可能還想添加一個可選的元素刪除器,以防萬一有人想要一些莫名其妙的原因使用你的模板與原始指針。

+0

瞭解,謝謝你的解釋。 –