复制构造函数而不是移动构造函数,为什么?

时间:2015-10-04 20:11:45

标签: c++11 move

考虑这个课程:

template<typename T> struct pooled_resource: T{
template<typename... Args> pooled_resource(std::list<T>& pool, Args&&... args):
    T(select_resource(pool, std::forward<Args>(args)...)), pool(pool){
    if(!pool.empty()) pool.pop_front();
}
~pooled_resource(){
    pool.push_front(static_cast<T&&>(*this));
}
private:
std::list<T>& pool;
template<typename... Args> static T select_resource(std::list<T>& pool, Args&&... args){
    if(pool.empty())
        return T(std::forward<Args>(args)...);
    else
        return std::move(pool.front());
}
};

它允许创建具有池化资源但在语义上等同于非池化版本的变量:

std::list<std::vector<int>> pool;
using pooled_vector = pooled_resource<std::vector<int>>;
{
    pooled_vector a(pool);          //pool is empty, allocate new resources
    { pooled_vector b(pool, 100); }     //allocate again, but then release to pool as b goes out of scope
    pooled_vector c(pool);              //reuse b's resources
    assert(c.size() == 100);
}

我的实际问题是,对于上面的简单情况,一切正常,并且调用了池化资源的移动构造函数。但是,我正在寻找另一个类,不调用移动构造函数,而是复制构造函数。确切地说,类是boost::compute::vector,它确实声明了一个移动构造函数,它似乎在boost::compute::vector<int> a; boost::compute::vector<int> b(std::move(a));这样的简单情况下工作。

我不知道为什么会发生这种情况而且我不知道如何诊断它:关于实际使用移动构造函数的规则我缺少什么?

1 个答案:

答案 0 :(得分:0)

所以问题是集合资源类中的一个愚蠢的错误。这是它的草图:

template<typename T, typename Allocator = DefaultAllocator> struct Resource{
    /*...*/
    Resource(Resource<T>&& o){ /*...*/ }
}

问题是移动构造函数的参数是Resource<T, DefaultAllocator>类型。由于我使用的是一些自定义分配器,实际上没有模板移动构造函数可用于通用Allocator,但只有通用类型T和分配器DefaultAllocator。该修复只需要省略移动构造函数的所有模板规范:

Resource(Resource&& o){ /*...*/ }

希望这可以挽救别人的下午。