c++ - 为什么 std::vector 不能保存常量对象?
问题描述
我不确定为什么不允许存在以下代码:
int main()
{
std::vector<const int> v;
v.reserve(2);
v.emplace_back(100);
v.emplace_back(200);
}
理论上,reserve()
不构造任何东西,与resize()
. 此外,emplace_back()
正在构建“就地”对象,因此这些代码都没有覆盖已经构建的常量对象。
尽管如此,即使写第一行 ,std::vector<const int> v;
也已经导致编译错误。为什么根本不允许有 a std::vector
of 常量?
解决方案
虽然最好在这里阅读“为什么”,但有一些简单的方法可以得到你想要的:
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);
如果您认为这对您的用例是合理的,您甚至可以决定您的包装器应该是“多么恒定”并提供移动构造函数(请注意,这t
本身不是恒定的)。as_const
请注意,您不能以这种方式禁止重新分配向量。如果您想这样做(并且不想使用编译时大小的数组,因为您现在的大小仅在运行时),请查看std::unique_ptr<T[]>
. 但请注意,在这种情况下,您首先必须创建一个可变变体,然后在 const 变体中重新安装它,因为底层数组已默认初始化,之后您无法更改任何内容。
当然,也有可能使用分配器并禁止重新分配。但这没有 stl 实现。这种行为有一些实现(我自己尝试过一次,但有点乱),但我不知道是否有任何提升。
推荐阅读
- python - 仅使用内置功能的具有正确数据类型的 YAML 到 Python 字典
- cmake - 使用 CMake 传递 LLVM 的编译器选项依赖项
- ios - 使用 SwiftUI 在 CoreData 中处理 Header / Detail 视图的正确方法
- html - 如何使包含跨度和不间断空格的标题包裹整个单词
- excel - excel VBA 代码中的自动化错误或错误 462
- typescript - Airtable Typescript - 从DefinitelyTyped 库中导入类型
- java - Thymeleaf 从请求或会话中获取当前语言环境
- python - 枕头,文本居中不起作用,这是如何完成的?
- go - 使用阅读器从 []byte 读取结构时出错
- django - BootstrapError:参数“form”应包含有效的 Django 表单