考虑这个课程:
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));
这样的简单情况下工作。
我不知道为什么会发生这种情况而且我不知道如何诊断它:关于实际使用移动构造函数的规则我缺少什么?
答案 0 :(得分:0)
所以问题是集合资源类中的一个愚蠢的错误。这是它的草图:
template<typename T, typename Allocator = DefaultAllocator> struct Resource{
/*...*/
Resource(Resource<T>&& o){ /*...*/ }
}
问题是移动构造函数的参数是Resource<T, DefaultAllocator>
类型。由于我使用的是一些自定义分配器,实际上没有模板移动构造函数可用于通用Allocator
,但只有通用类型T
和分配器DefaultAllocator
。该修复只需要省略移动构造函数的所有模板规范:
Resource(Resource&& o){ /*...*/ }
希望这可以挽救别人的下午。