- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
假设我有一个 C++ 类,Container
,其中包含一些类型为 Element
的元素.由于各种原因,在构造后修改或替换内容是低效的、不可取的、不必要的、不切实际的和/或不可能的 (1)。类似于 const std::list<const Element>
的内容(2).
Container
可以满足STL的“容器”和“序列”概念的很多要求。它可以提供各种类型,如 value_type
, reference
等。它可以提供默认构造函数、复制构造函数、const_iterator
。类型,begin() const
, end() const
, size
, empty
,所有的比较运算符,也许还有一些 rbegin() const
, rend() const
, front()
, back()
, operator[]()
, 和 at()
.
然而,Container
无法提供 insert
, erase
, clear
, push_front
, push_back
, 非常量 front
, 非常量 back
, 非常量 operator[]
, 或非常量 at
具有预期的语义。所以看起来 Container
不能称为“序列”。此外,Container
无法提供 operator=
, 和 swap
, 它不能提供 iterator
指向非常量元素的类型。所以,它连“容器”的资格都算不上。
是否有一些功能较弱的 STL 概念 Container
满足?是否存在“只读容器”或“不可变容器”?
如果Container
不满足任何定义的一致性级别,部分一致性是否有值(value)?当它不符合条件时,让它看起来像一个“容器”是否具有误导性?有没有一种简明、明确的方式可以记录一致性,这样我就不必明确记录一致性语义?同样,一种记录它的方法,以便 future 的用户知道他们可以利用只读通用代码,但不要指望变异算法起作用?
如果我放松问题,我会得到什么 Container
是可分配的(但它的元素不是)?那时,operator=
和 swap
是可能的,但取消引用 iterator
仍然返回 const Element
.是否Container
现在有资格成为“容器”了吗?
const std::list<T>
具有与 Container
大致相同的界面.这是否意味着它既不是“容器”也不是“序列”?
脚注 (1) 我有涵盖整个范围的用例。我有一个想成为容器的类,它适应一些只读数据,所以它必须是不可变的。我有一个可能的容器,它会根据需要生成自己的内容,因此它是可变的,但您不能按照 STL 要求的方式替换元素。我还有另一个可能的容器,它以一种可以使 insert()
的方式存储它的元素。太慢了,它永远不会有用。最后,我有一个字符串,它以 UTF-8 格式存储文本,同时公开一个面向代码点的接口(interface);可变实现是可能的,但完全没有必要。
脚注 (2) 这只是为了说明。我很确定std::list
需要可分配的元素类型。
最佳答案
STL 没有定义任何更小的概念;主要是因为 const
的想法通常是在每个迭代器或每个引用级别而不是每个类级别上表达的。
你不应该提供具有意外语义的iterator
,只提供const_iterator
。如果客户端代码出错,这允许客户端代码在最合乎逻辑的地方(具有最易读的错误消息)失败。
可能最简单的方法是封装它并防止所有非常量别名。
class example {
std::list<sometype> stuff;
public:
void Process(...) { ... }
const std::list<sometype>& Results() { return stuff; }
};
现在任何客户端代码都清楚地知道他们可以用需要突变的 Results-nada 的返回值做什么。
关于c++ - 不可变的 C++ 容器类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5478866/
COW 不是奶牛,是 Copy-On-Write 的缩写,这是一种是复制但也不完全是复制的技术。 一般来说复制就是创建出完全相同的两份,两份是独立的: 但是,有的时候复制这件事没多大必要
我是一名优秀的程序员,十分优秀!