c++ - 如何从仅提供复制构造函数的类实例化 "empty"对象?

标签 c++ boost stl queue condition-variable

我实现了一个线程安全的模板化队列:

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/

相关文章:

c++ - 在运行时更改为 n 个维度

c++ - 用C++打开目录中的HTML文件

c++ - 不区分大小写的 std::string.find()

c++ - 在 openmp 中迭代 std 容器

c++ - 为什么我可以返回本地 int& 并获得一定的值(value)而不是垃圾? C++

c++ - 将指针连接到 boost::signals2

c++ - 使用 zlib 压缩 boost 二进制文件

c++ - 在字符串正则表达式 C++ 中查找模式

c++ - 为什么这个迭代器是常量的?

c++ - 从 unordered_multiset 中只删除一项