2017-07-28 55 views
0

短缺問題隊列包裝問題:什麼明顯的錯誤(誤會?)我是用SafeQueue內使用std::is_pointer和/或std::is_array ::明確()在做什麼?目的是檢查指針隊列,然後檢查指針是否爲unsigned char*char*陣列。C++:使用模板

這是在C++ 11中,將std::queue類包裝起來,以使線程安全。

#ifndef SAFEQUEUE_H 
#define SAFEQUEUE_H 

#include <queue> 
#include <mutex> 
#include <type_traits> 

template <typename T> 
class SafeQueue 
{ 
    public: 
     SafeQueue() = default; // default ctor 
     SafeQueue(const SafeQueue&) = delete; // disable copy 
     SafeQueue& operator=(const SafeQueue&) = delete; // disable assignment 

     bool empty() const 
     { 
      std::unique_lock<std::mutex> ulock(m_mutex); 
      return m_queue.empty(); 
     } 

     T& front() // never called without empty() or size() > 0 check 
     { 
      std::unique_lock<std::mutex> lock(m_mutex); 
      if(!m_queue.empty()) { return m_queue.front(); } 
     } 

     void clear() 
     { 
      std::unique_lock<std::mutex> lock(m_mutex); 
      if(m_queue.empty()) { return; } // quick exit 

      bool isPointers = (std::is_pointer<T>::value) ? true : false; // always returns true on class objects 
      if(isPointers) 
      { 
       //bool isarray = std::is_array<T>::value ? true : false; // always returns true on class objects 
       bool isarray = (std::is_same<unsigned char*, T>::value || std::is_same<char*, T>::value) ? true : false; // also returns true always 
       while(!m_queue.empty()) 
       { 
        if(isarray) { delete[] m_queue.front(); m_queue.front() = nullptr; } 
        else { delete[] m_queue.front(); m_queue.front() = nullptr; } 
        m_queue.pop(); 
       } 
      } 
      else { std::queue<T>().swap(m_queue); } 
     } 

     void pop() 
     { 
      std::unique_lock<std::mutex> lock(m_mutex); 
      if(!m_queue.empty()) { m_queue.pop(); } 
     } 

     unsigned int size() const 
     { 
      std::unique_lock<std::mutex> lock(m_mutex); 
      return m_queue.size(); 
     } 

     void push(const T& item) 
     { 
      std::unique_lock<std::mutex> lock(m_mutex); 
      m_queue.push(item); 
     } 

    protected: 
     mutable std::mutex m_mutex; 
     std::queue<T> m_queue; 
}; 

#endif // SAFEQUEUE_H 
+0

你怎麼知道這些行「總是迴歸真實」?實際的具體行爲是什麼讓你覺得呢? [MCVE]表示*包含特定問題或錯誤*;你對這種錯誤發生的解釋是不夠的。 – Yakk

回答

1

即使控件是false,也會編譯所有分支。

因爲對於T=int,delete[]所調用的int不是合法的C++,所以您正在構建中斷。

解決問題的方法是不要存儲原始數組char*,而是在隊列中使用智能指針std::unique_ptr<char[]>std::unique_ptr<unsigned char[]>

你可以用一種特質做到這一點:

template<class T> struct queued_type{ 
    using type=T; 
    using extracted_type=T&; 
    static extracted_type extract(type& out){ return out; } 
    static type& box(T& in){ return in; } 
}; 
template<class T> struct queued_type<T*>{ 
    using type=std::unique_ptr<T[]>; 
    using extracted_type=type; 
    static extracted_type extract(type& out){ return out.release(); } 
    static type box(type& in){ return type(in); } 
}; 
template<class T>using queued_type_t=typename queued_type<T>::type; 

現在存儲std::queue<queued_type_t<T>>push做了m_queue.push(queued_type<T>::box(in));,front做了queued_type<T>::extract(m_queue.front())並返回了typename queued_type<T>::extracted_type

而且清楚的是std::queue<queued_type_t<T>>{}.swap(m_queue);沒有邏輯。