【问题标题】:Can a C++ allocator be final?C++ 分配器可以是最终的吗?
【发布时间】:2019-08-14 01:34:34
【问题描述】:

cppreference page for the Allocator requirement 没有说 Allocator 必须是可继承的,即它没有说 Allocator 不能是最终的。

但是,在许多库中,分配器是私有继承的,以利用无状态分配器的空基类优化。例如:

template <typename T, typename A = std::allocator<T>>
class Dummy_vector :private A {
    // ...
    A get_alloc() const
    {
        return static_cast<A>(*this);
    }
    // ...
};

如果A 是最终的,则此实现会中断。

分配器可以是最终的吗?我错过了什么?或者这样的实现是否应该包含用于最终 Allocators 的特殊代码?

(注意:“最终分配器s的特殊代码,”我的意思是这样的:

template <
    typename T,
    typename A = std::allocator<T>,
    bool = std::is_final<A>
>
class Dummy_vector :private A {
    // version for nonfinal allocators
    // ...
    A get_alloc() const
    {
        return static_cast<A>(*this);
    }
    // ...
};

template <typename T, typename A>
class Dummy_vector<T, A, true> {
    // special version for final allocators
};

)

【问题讨论】:

    标签: c++ inheritance memory-management final allocator


    【解决方案1】:

    这确实是个问题。另见C++ Standard Library Defect Report 2112。该标准不要求可以派生分配器类型。但是,该标准也没有指定实现派生自分配器类型。因此,共识似乎是,这将被认为是实现的错误,因为没有检查分配器类型是否可以从……派生而来。

    【讨论】:

    • 其实我觉得应该算是标准库实现中的一个bug吧……
    • 谢谢!我同意该标准包含关于“分配器不能是非类类型 [...] 因此,始终可以从分配器创建派生类”的逻辑错误。因为它没有考虑最终。标准库实现是无辜的;-)
    • 好的。无论如何,当我写我的容器时,我会检查final
    • @L.F.我编辑了我的答案;我删除了我称之为标准中的错误的部分。我忽略了缺陷报告已被标记为用 C++14 解决。那里的讨论会让我得出这样的结论,即至少从 C++14 开始,这个问题被认为是实现问题而不是规范问题……
    • @L.F.从 C++ 20 开始,[[no_unique_address]] 属性应该消除在这种情况下从用户提供的类型派生的原因,以及这样做带来的所有问题……
    猜你喜欢
    • 2018-05-13
    • 2012-03-07
    • 1970-01-01
    • 2011-04-05
    • 2010-10-15
    • 2018-01-22
    • 2017-12-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多