【问题标题】:Should allocator::get_deleter() be const qualified?allocator::get_deleter() 应该是 const 限定的吗?
【发布时间】:2018-08-21 15:11:36
【问题描述】:

我正在尝试为我的无锁分配器类模板提供get_deleter()(代码为here)。删除器类似于

template <typename T>
struct deleter {
  allocator<T>& alloc;
  void operator()(T* p) const noexcept {
    p->~T();
    alloc.deallocate(p);
  }
};

注意alloc 不应该是const,因为deallocate() 不是const,它与std::allocator::deallocate() 对齐。现在,我不确定我的allocator::get_deleter() 是否应该是const。困境如下:

1.成为const 的理由: 该方法本身不会修改*this,并且是线程安全的(另见Does const mean thread-safe in C++11?)。

2。不是const的理由: 该方法返回一个deleter,可以用来修改*this。如果方法是const,也可以避免const_cast()。

有什么建议或想法吗?就个人而言,我赞成const。

【问题讨论】:

  • 如果将其标记为 const 意味着我可以删除一个 const 对象而不会收到任何警告,我个人会赞成这个意图而不是将其标记为 const。听起来不像是我想要允许的。或许两者都提供?
  • @spectras 但是你可以调用const 对象的析构函数,对吧?然而,operator delete() 不接受 const 指针。多么两难:(
  • 这是一个明确的例外:“可以为 const、volatile 或 const volatile 对象调用析构函数。 [...] const 和 volatile 语义不适用于正在销毁的对象”。见stackoverflow.com/a/2271055/3212865
  • @spectras 那么我认为这个异常也应该适用于deallocation,否则const对象的内存无法回收。 deleter 只做这两件事:销毁和解除分配。
  • 我明白你的意思。确实可以删除一个 const 对象。实际上,您的删除器正在运行析构函数,因此用于证明销毁异常合理的相同论点确实适用。

标签: c++ constants api-design allocator


【解决方案1】:

不要const_cast&lt;allocator &amp;&gt;(*this)

您不知道是否有人会拥有 const allocator&lt;...&gt; 值并获得未定义的行为。即使你不这样做,你也在撒谎const 的真实情况。

allocator::get_deleter 不能是没有const_cast 的const,所以它不应该。

See it live

【讨论】:

  • 这已经在问题中作为非常量的专业人士进行了讨论。
  • 编辑得更具体。仅仅因为const_cast 存在,并不意味着你应该使用它
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-05-12
  • 1970-01-01
  • 2012-08-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多