我实现了一个线程安全的模板化队列:
template<class T> class queue {
private:
boost::mutex mutex;
boost::condition_variable emptyCondition;
boost::condition_variable fullCondition;
boost::scoped_ptr< std::queue<T> > std_queue;
...
public:
...
T pop() {
T r; // [*]
{
boost::mutex::scoped_lock popLock(mutex);
while (queueIsEmpty())
emptyCondition.wait(popLock);
r = std_queue->front();
std_queue->pop();
}
fullCondition.notify_one();
return r;
}
...
我无法以我的方式实例化对象(用 [*]
标记的地方),因为缺少 T
的构造函数,没有形式参数。
所以:有没有办法,也许使用指向 T
的指针和复制构造函数(我知道它是为每个 T
实现的),以避免许多模板特化?
编辑 1
我也想到了这个可能的解决方案。
T pop() {
boost::mutex::scoped_lock popLock(mutex);
while (queueIsEmpty())
emptyCondition.wait(popLock);
T r(std_queue->front());
std_queue->pop();
// update overall number of pop
popNo++;
popLock.unlock();
fullCondition.notify_one();
return r;
}
它会起作用吗?
最佳答案
此场景的一个选项是使用 boost::optional
:
T pop() {
boost::optional<T> r;
{
boost::mutex::scoped_lock popLock(mutex);
while (queueIsEmpty())
emptyCondition.wait(popLock);
r = std_queue->front();
std_queue->pop();
}
fullCondition.notify_one();
return *r; // r is guaranteed to be engaged at this point
}
boost::optional
会在运行时注意跟踪其包含的 T
是否已构建,以及是否需要销毁它。 (请注意,此处您实际上不需要 boost::mutex::scoped_lock 的全部功能;您可以使用
boost::lock_guard`。)
另一种方法是注意可以释放 scoped_lock
:
T pop() {
boost::mutex::scoped_lock popLock(mutex);
while (queueIsEmpty())
emptyCondition.wait(popLock);
T r = std_queue->front();
std_queue->pop();
popLock.release();
fullCondition.notify_one();
return r;
}
这里的缺点是不太清楚 popLock
的范围是什么,并且代码更改可能导致不安全代码或死锁。
关于c++ - 如何从仅提供复制构造函数的类实例化 "empty"对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25890994/