2017-07-28 51 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);没有逻辑。