繁体   English   中英

为什么 std::vector 不能保存常量对象?

[英]Why can't a std::vector hold constant objects?

我不确定为什么不允许存在以下代码:

int main()
{
    std::vector<const int> v;
    v.reserve(2);
    v.emplace_back(100);
    v.emplace_back(200);
}

理论上,与resize()相反, reserve()不构造任何东西。 此外, emplace_back()正在构造“就地”对象,因此这些代码都不会覆盖已构造的常量 object。

尽管如此,即使写第一行, std::vector<const int> v; , 已经导致编译错误。 为什么根本不允许有一个std::vector常量?

正如 Bathsheba 提供的链接告诉您的那样,问题在于std::vector<T>实际上是std::vector<T, std::allocator<T>> 在 C++20 之前, std::allocator<T>::address()有两个重载,一个采用T& ,另一个采用T const& T=const int的问题应该很明显。 C++ 没有额外的常量,所以两个重载同样好。

虽然最好在这里阅读“为什么”,但有一些简单的方法可以得到你想要的:

template<class T>
class as_const {
    T t;
public:
    as_const(T& t_): t(t_) {}
    as_const(const as_const&) = default;
    as_const(as_const &&) = delete;
    as_const& operator=(const as_const&) = default;
    as_const& operator=(as_const&&) = delete;

    operator const T&() const {
       return t;
    }
    const T& operator*() const { 
    // Or just a get method, anyway it's nicer to also have an explicit getter
       return t;
    }
};

std::vector<as_const<int>> vec;
vec.reserve(2)
vec.emplace_back(100);
vec.emplace_back(200);

如果您认为这对您的用例是合理的,您甚至可以决定您的包装器应该是“多么恒定”并提供移动构造函数(请注意, tas_const中本身不是恒定的)。

请注意,您不能以这种方式禁止重新分配向量。 如果您想这样做(并且不想使用编译时大小的数组,因为您现在只在运行时使用您的大小)请查看std::unique_ptr<T[]> 但请注意,在这种情况下,您首先必须创建一个可变变体,然后在 const 变体中重新安装它,因为底层数组已默认初始化,之后您无法更改任何内容。

当然,也有可能使用分配器并禁止重新分配。 但这没有 stl 实现。 这种行为有一些实现(我自己尝试过一次,但有点乱),但我不知道是否有任何提升。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM