【问题标题】:trivial allocator aware container?微不足道的分配器感知容器?
【发布时间】:2016-09-08 01:21:26
【问题描述】:

我正在研究/玩分配器,试图了解它是如何工作的。但是我在尝试实现接受分配器的琐碎容器时遇到了问题。现在我结束了:

template<class T, class Allocator =std::allocator<T>> class Container {
public:
    using allocator_type    = Allocator;
    using value_type        = T;
    using pointer           = typename std::allocator_traits<allocator_type>::pointer;
    using reference         = value_type&;
    using size_type         = std::size_t;

    Container( size_type n =0 , const allocator_type& allocator =allocator_type() ){
        std::cout << "ctor" << std::endl;
        allocator.allocate(n);
    };
};

int main(int argc, const char* argv[]){
    Container<int> c {5};
    return 0;
}

它给了我一个错误member function 'allocate' not viable: 'this' argument has type 'const allocator_type' (aka 'const std::__1::allocator&lt;int&gt;'), but function is not marked const

请问如何解决这个错误?我错过了什么吗? 我打算稍后使用特征,但想先使用旧方法使其工作。

【问题讨论】:

  • 标记const的不是函数而是allocator。您可能想看看 libc++、libstdc++ 是如何以 std::vector 之类的方式实现的。
  • 标准容器通常使用这个 const 引用来初始化它们自己的成员(或基类),而不是在这个成员上调用 allocate。

标签: c++ allocator


【解决方案1】:

你的线路

allocator.allocate(n);

尝试调用allocatorallocate 方法,该方法未定义为const 方法。但是,如果您看一下,allocator 的类型是 const allocator_type&amp;,即对 allocator_type 的 const 引用。

那你怎么用呢?您通常可以对 const 对象(或对一个对象的引用)做的一件事是从它构造一个不同的非常量对象。例如,这会构建:

allocator_type(allocator).allocate(n);

正如 SergeyA 在 cmets 中正确指出的那样,不构建临时临时 allocator_type 而是创建这样的成员是相当普遍的:

    allocator_type m_alloc; // Should probably be private

    Container( size_type n =0 , const allocator_type& allocator =allocator_type() ) : 
            m_alloc{allocator}{
        std::cout << "ctor" << std::endl;
        m_alloc.allocate(n);
    };

【讨论】:

  • 将 const_cast 去掉会是个坏习惯吗?虽然让它成为会员看起来很自然和优雅。
  • @JiříLechner const_casts 通常是某些问题的明显迹象。同样,正如您所指出的,这里有一种非常自然的方法可以绕过它,为什么不呢?
  • 还有一个问题。我想使用 unique_ptr。对将返回 unique_ptr 的分配器进行专门化是个好主意还是超出了分配器的工作范围?
  • @JiříLechner 实际上,如果您使用unique_ptr,您可能只想使用set your allocator's deallocate as its deallocator。我个人会避免这个方向。如果您确实在编写容器,那么在极少数情况下,让析构函数显式释放内存可能会更简单。
  • 你的意思是把unique_ptr的deleter设置为allocator的deallocate()?
猜你喜欢
  • 2017-04-09
  • 2023-04-04
  • 1970-01-01
  • 2017-01-30
  • 2016-08-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-07
相关资源
最近更新 更多