2011-05-09 30 views
3

我有一个Visual Studio 2008 C++应用程序,我正在实现替换容器中使用的标准分配器,如std::vector。但是,我遇到了一个问题。我的实现依赖于拥有资源句柄的分配器。在使用rebind功能的情况下,我需要将句柄的所有权转移给新的分配器。事情是这样的:在std :: allocator上传递对象的所有权rebind

template< class T > 
class MyAllocator 
{ 
public: 
    template< class U > 
    explicit MyAllocator(const MyAllocator<U>& other) throw() 
     : h_(other.Detach()) // can't do this to a `const` 
    { 
    }; 

    // ... 

private: 
    HANDLE Detach() 
    { 
     HANDLE h = h_; 
     h_ = NULL; 
     return h; 
    }; 

    HANDLE h_; 
}; // class MyAllocator 

不幸的是,我不能,因为它是const缓解手柄所有权的老分配器。如果我从rebind构造函数中删除const,那么容器将不会接受它。

error C2558: class 'MyAllocator<T>' : no copy constructor available or copy constructor is declared 'explicit' 

是否有解决此问题的好方法?

感谢,

PaulH

+0

不需要分配器不需要状态?关于分配器的经典文章,Matt Austern,IIRC,但我现在找不到它... – sbi 2011-05-09 19:32:54

+2

这里是文章:[http://drdobbs.com/cpp/184403759](http://drdobbs。 COM/CPP/184403759)。从快速浏览[this discussion](http://gcc.gnu.org/ml/libstdc++/2004-10/msg00303.html),似乎确实支持有状态分配器,尽管std lib实现支持用于成为一个问题。 – sbi 2011-05-09 19:36:10

+0

@sbi - 感谢您的文章和讨论。我打算跟进一个关于如何处理'std :: swap'的问题。 – PaulH 2011-05-09 19:44:03

回答

1

如果声明h_作为mutable会发生什么?

2

不太了解分配器(从不需要它们):您的副本需要const ref,因此承诺不会更改other对象,但您仍尝试对其进行更改。虽然有类的设计方式(std::auto_ptr),这确实看起来很腥。
在语法上,你总是可以宣布h_mutable,使Detach()一个const成员函数,但我严重质疑的语义此设置的,使用大刀通过句法丛林黑客我的路前。

1

你可以用一个额外的间接寻址来解决这个问题,但它不是一个理想的解决方案。基本上,您的分配器将有一个指针到将在构造函数/析构函数中分配/释放的句柄。它指向的句柄在整个过程中都是非const的,因此您可以将句柄从一个分配器“移动”到另一个分配器。尽管如此,这确实给分配器增加了一些开销。

我不知道你的确切情况,但它似乎是一个非平凡可复制的状态分配器应该仔细考虑所有的影响。有没有另外一种方法可以简化其设计,因此它没有移动专用手柄?

1

,则不能传输的所有权,因为分配器可以被复制并且甚至在单个容器中,并同时使用所得到的情况下反弹多次。

你必须共享资源来代替。使用引用计数为资源创建间接引导。喜欢的东西:

class SharedHandle { 
    HANDLE h_; 
    int count; 
    SharedHandle(HANDLE h) : h_(h), count(1) {} 
    ~SharedHandle() { CloseHandle(h_); } // or whatever to release the resource. 
    SharedHandle *Ref() { ++count; return this; } 
    void Unref() { if(!--count) delete this; } 
} 

比:

explicit MyAllocator(const MyAllocator<U>& other) throw() 
: h_(other.h_->Ref()) 

除了自然需要分配异质块像hash_map/unordered_map容器,容器的微软实现被称为分配各种奇怪的事情。当我在一个Windows应用程序中追踪分配时,有很多来自STL内部的奇怪大小的分配。

相关问题