STL向量和具有自定义删除器类的唯一\u ptr 我有一些C++代码,用CLAN 3.2-7和GCC 4.8-1编译,但不是用GCC 4.63.我正在使用c++0x进行编译

STL向量和具有自定义删除器类的唯一\u ptr 我有一些C++代码,用CLAN 3.2-7和GCC 4.8-1编译,但不是用GCC 4.63.我正在使用c++0x进行编译,c++,unique-ptr,C++,Unique Ptr,我正在实现一个“资源池”,它管理一组固定的资源。它通过提供具有自定义删除器类的唯一_ptr来分配资源;当请求资源的对象退出范围时,删除程序将资源返回到池中 deleter类如下所示: template <typename T> class ResourcePoolManager { public: ResourcePoolManager(ResourcePool<T> & pool) : pool(pool) { } ~R

我正在实现一个“资源池”,它管理一组固定的资源。它通过提供具有自定义删除器类的唯一_ptr来分配资源;当请求资源的对象退出范围时,删除程序将资源返回到池中

deleter类如下所示:

template <typename T>
class ResourcePoolManager {
public:
    ResourcePoolManager(ResourcePool<T> & pool)
    : pool(pool)
    {
    }

    ~ResourcePoolManager() {};

    void operator()(T* releasedResource) const {
        pool.releaseResource(releasedResource);
    }
private:
    ResourcePool<T> & pool;
};
正如上面提到的,clang和一个更新的版本是gcc,可以使用它。然而,gcc 4.6.3给出了:

/usr/include/c++/4.6/bits/unique_ptr.h: In member function 'std::unique_ptr<_Tp, _Dp>& std::unique_ptr<_Tp, _Dp>::operator=(std::unique_ptr<_Tp, _Dp>&&) [with _Tp = OpenCLDevice, _Dp = ResourcePoolManager<OpenCLDevice>, std::unique_ptr<_Tp, _Dp> = std::unique_ptr<OpenCLDevice, ResourcePoolManager<OpenCLDevice> >]':
/usr/include/c++/4.6/bits/vector.tcc:319:4:   instantiated from 'void std::vector<_Tp, _Alloc>::_M_insert_aux(std::vector<_Tp, _Alloc>::iterator, _Args&& ...) [with _Args = {std::unique_ptr<OpenCLDevice, ResourcePoolManager<OpenCLDevice> >}, _Tp = std::unique_ptr<OpenCLDevice, ResourcePoolManager<OpenCLDevice> >, _Alloc = std::allocator<std::unique_ptr<OpenCLDevice, ResourcePoolManager<OpenCLDevice> > >, std::vector<_Tp, _Alloc>::iterator = __gnu_cxx::__normal_iterator<std::unique_ptr<OpenCLDevice, ResourcePoolManager<OpenCLDevice> >*, std::vector<std::unique_ptr<OpenCLDevice, ResourcePoolManager<OpenCLDevice> > > >, typename std::_Vector_base<_Tp, _Alloc>::_Tp_alloc_type::pointer = std::unique_ptr<OpenCLDevice, ResourcePoolManager<OpenCLDevice> >*]'
/usr/include/c++/4.6/bits/vector.tcc:102:4:   instantiated from 'void std::vector<_Tp, _Alloc>::emplace_back(_Args&& ...) [with _Args = {std::unique_ptr<OpenCLDevice, ResourcePoolManager<OpenCLDevice> >}, _Tp = std::unique_ptr<OpenCLDevice, ResourcePoolManager<OpenCLDevice> >, _Alloc = std::allocator<std::unique_ptr<OpenCLDevice, ResourcePoolManager<OpenCLDevice> > >]'
/usr/include/c++/4.6/bits/stl_vector.h:840:9:   instantiated from 'void std::vector<_Tp, _Alloc>::push_back(std::vector<_Tp, _Alloc>::value_type&&) [with _Tp = std::unique_ptr<OpenCLDevice, ResourcePoolManager<OpenCLDevice> >, _Alloc = std::allocator<std::unique_ptr<OpenCLDevice, ResourcePoolManager<OpenCLDevice> > >, std::vector<_Tp, _Alloc>::value_type = std::unique_ptr<OpenCLDevice, ResourcePoolManager<OpenCLDevice> >]'
trunk/src/dpa/distinguishers/GenericOpenCLDPA.cpp:109:39:   instantiated from here
/usr/include/c++/4.6/bits/unique_ptr.h:176:2: error: use of deleted function 'ResourcePoolManager<OpenCLDevice>& ResourcePoolManager<OpenCLDevice>::operator=(const ResourcePoolManager<OpenCLDevice>&)'

ResourcePool.hpp:30:7 error: 'ResourcePoolManager<OpenCLDevice> & ResourcePoolManager<OpenCLDevice>::operator=(const ResourcePoolManager<OpenCLDevice>&)' 
is implicitly deleted because the default definition would be ill-formed:
ResourcePool.hpp:30:7: error: non-static reference member 'ResourcePool<OpenCLDevice>& ResourcePoolManager<OpenCLDevice>::pool', can't use default assignment operator
/usr/include/c++/4.6/bits/unique\u ptr.h:在成员函数“std::unique\u ptr&std::unique\u ptr::operator=(std::unique\u ptr&)[with the  \u Tp=OpenCLDevice,_Dp=ResourcePoolManager,std::unique\u ptr=std::unique\u ptr&]:
/usr/include/c++/4.6/bits/vector.tcc:319:4:从“void std::vector::_M_insert_aux(std::vector::iterator,_Args&&…[带_Args={std::unique_ptr},_Tp=std::unique_ptr,_Alloc=std::Alloc::分配器,std::vector::iterator=u gnu cxx:::u normal iterator,tyname std:u vector:u-vector基::u-type=Alloc::unique:]
/usr/include/c++/4.6/bits/vector.tcc:102:4:从“void std::vector::emplace_back”(_Args&&…[带_Args={std::unique_ptr},_Tp=std::unique_ptr,_Alloc=std::allocator])实例化
/usr/include/c++/4.6/bits/stl_vector.h:840:9:从“void std::vector::push_back(std::vector::value_type&&)[with the _Tp=std::unique_ptr,_Alloc=std::分配器,std::vector::value_type=std::unique_ptr]实例化
trunk/src/dpa/discrimiters/genericopensldpa.cpp:109:39:从此处实例化
/usr/include/c++/4.6/bits/unique\u ptr.h:176:2:错误:使用已删除的函数“ResourcePoolManager&ResourcePoolManager::operator=(const ResourcePoolManager&)”
ResourcePool.hpp:30:7错误:“ResourcePoolManager和ResourcePoolManager::operator=(const ResourcePoolManager&)”
被隐式删除,因为默认定义的格式不正确:
ResourcePool.hpp:30:7:错误:非静态引用成员“ResourcePool&ResourcePoolManager::pool”,无法使用默认分配运算符
编译器在指针移动到
gpu
向量的最后一行停止,这向我表明某些内容在不应该被复制的情况下被复制。第30行是ResourcePoolManager类
类ResourcePoolManager{
的定义


我对自定义删除程序的管理有什么不正确的地方吗?更新的编译器让我可以逍遥法外。

看起来像libstdc++4.6
unique\u ptr中的一个bug,它希望删除程序类型是可复制的

更具体地说,此程序会复制错误:

#include <memory>
#include <vector>

struct deleter {
    deleter() : c(*"") {}
    void operator () (int *) const {}
    deleter(deleter&&) = default;
    deleter& operator = (deleter&&) = default;
    const char& c;
};

int main() {
    std::vector<std::unique_ptr<int, deleter>> vec;
    vec.push_back(std::unique_ptr<int, deleter>{});
}

被指定为只要求
T
MoveInsertable
,因此我相信这肯定是libstdc++4.6中的一个错误。

您能标记第30行吗?当然——这是“类资源池管理器{”错误消息还有其他内容吗?编译器想复制删除器对象。这是不可能的,因为成员
ResourcePool&pool;
。我不确定编译器是否需要复制删除器,但似乎可以解决。我猜它想复制这样的行…
return std::unique\u ptr(资源,管理器);
您可以使用
std::unique_ptr(NULL,manager);
(即使用删除器类型的引用)看起来像libstdc++4.6
unique_ptr中的一个bug,它期望删除器类型是可复制的。
/usr/include/c++/4.6/bits/unique_ptr.h: In member function 'std::unique_ptr<_Tp, _Dp>& std::unique_ptr<_Tp, _Dp>::operator=(std::unique_ptr<_Tp, _Dp>&&) [with _Tp = OpenCLDevice, _Dp = ResourcePoolManager<OpenCLDevice>, std::unique_ptr<_Tp, _Dp> = std::unique_ptr<OpenCLDevice, ResourcePoolManager<OpenCLDevice> >]':
/usr/include/c++/4.6/bits/vector.tcc:319:4:   instantiated from 'void std::vector<_Tp, _Alloc>::_M_insert_aux(std::vector<_Tp, _Alloc>::iterator, _Args&& ...) [with _Args = {std::unique_ptr<OpenCLDevice, ResourcePoolManager<OpenCLDevice> >}, _Tp = std::unique_ptr<OpenCLDevice, ResourcePoolManager<OpenCLDevice> >, _Alloc = std::allocator<std::unique_ptr<OpenCLDevice, ResourcePoolManager<OpenCLDevice> > >, std::vector<_Tp, _Alloc>::iterator = __gnu_cxx::__normal_iterator<std::unique_ptr<OpenCLDevice, ResourcePoolManager<OpenCLDevice> >*, std::vector<std::unique_ptr<OpenCLDevice, ResourcePoolManager<OpenCLDevice> > > >, typename std::_Vector_base<_Tp, _Alloc>::_Tp_alloc_type::pointer = std::unique_ptr<OpenCLDevice, ResourcePoolManager<OpenCLDevice> >*]'
/usr/include/c++/4.6/bits/vector.tcc:102:4:   instantiated from 'void std::vector<_Tp, _Alloc>::emplace_back(_Args&& ...) [with _Args = {std::unique_ptr<OpenCLDevice, ResourcePoolManager<OpenCLDevice> >}, _Tp = std::unique_ptr<OpenCLDevice, ResourcePoolManager<OpenCLDevice> >, _Alloc = std::allocator<std::unique_ptr<OpenCLDevice, ResourcePoolManager<OpenCLDevice> > >]'
/usr/include/c++/4.6/bits/stl_vector.h:840:9:   instantiated from 'void std::vector<_Tp, _Alloc>::push_back(std::vector<_Tp, _Alloc>::value_type&&) [with _Tp = std::unique_ptr<OpenCLDevice, ResourcePoolManager<OpenCLDevice> >, _Alloc = std::allocator<std::unique_ptr<OpenCLDevice, ResourcePoolManager<OpenCLDevice> > >, std::vector<_Tp, _Alloc>::value_type = std::unique_ptr<OpenCLDevice, ResourcePoolManager<OpenCLDevice> >]'
trunk/src/dpa/distinguishers/GenericOpenCLDPA.cpp:109:39:   instantiated from here
/usr/include/c++/4.6/bits/unique_ptr.h:176:2: error: use of deleted function 'ResourcePoolManager<OpenCLDevice>& ResourcePoolManager<OpenCLDevice>::operator=(const ResourcePoolManager<OpenCLDevice>&)'

ResourcePool.hpp:30:7 error: 'ResourcePoolManager<OpenCLDevice> & ResourcePoolManager<OpenCLDevice>::operator=(const ResourcePoolManager<OpenCLDevice>&)' 
is implicitly deleted because the default definition would be ill-formed:
ResourcePool.hpp:30:7: error: non-static reference member 'ResourcePool<OpenCLDevice>& ResourcePoolManager<OpenCLDevice>::pool', can't use default assignment operator
#include <memory>
#include <vector>

struct deleter {
    deleter() : c(*"") {}
    void operator () (int *) const {}
    deleter(deleter&&) = default;
    deleter& operator = (deleter&&) = default;
    const char& c;
};

int main() {
    std::vector<std::unique_ptr<int, deleter>> vec;
    vec.push_back(std::unique_ptr<int, deleter>{});
}
int main() {
    std::vector<std::unique_ptr<int, deleter>> vec;
    vec.push_back(std::unique_ptr<int, deleter>{new int(42)});
    vec[0] = std::unique_ptr<int, deleter>{new int(42)};
}