不可变C++;集装箱类 我有一个C++类,容器> /Cult>,它包含了一些类型的元素:元素< />代码>。由于各种原因,在施工后修改或更换内容是低效的、不可取的、不必要的、不切实际的和/或不可能的(1)。类似于const std::list(2)的东西

不可变C++;集装箱类 我有一个C++类,容器> /Cult>,它包含了一些类型的元素:元素< />代码>。由于各种原因,在施工后修改或更换内容是低效的、不可取的、不必要的、不切实际的和/或不可能的(1)。类似于const std::list(2)的东西,c++,stl,C++,Stl,Container可以满足STL的“Container”和“sequence”概念的许多要求。它可以提供各种类型,如value\u type,reference,等等。它可以提供默认构造函数、副本构造函数、常量迭代器type、begin()const、end()const、size、empty、所有比较运算符,可能还有一些rbegin()常量,rend()常量,front(),back(),操作符[](),和at() 但是,容器不能提供具有预期语义的插入,擦除,清除,向前推,向后推,向前推,向后

Container
可以满足STL的“Container”和“sequence”概念的许多要求。它可以提供各种类型,如
value\u type
reference
,等等。它可以提供默认构造函数、副本构造函数、常量迭代器
type、
begin()const
end()const
size
empty
、所有比较运算符,可能还有一些
rbegin()常量
rend()常量
front()
back()
操作符[]()
,和
at()

但是,
容器
不能提供具有预期语义的
插入
擦除
清除
向前推
向后推
向前推
,向后推
非常量,非常量运算符[],或非常量。因此,
容器
似乎不能称为“序列”。此外,
容器
不能提供
操作符=
交换
,也不能提供指向非常量元素的
迭代器
类型。因此,它甚至不能称为“容器”

是否有一些
容器
满足的能力较差的STL概念?是否存在“只读容器”或“不可变容器”

如果
容器
不符合任何定义的一致性级别,则部分一致性是否有价值?当它不合格时,让它看起来像一个“容器”是误导吗?是否有一种简洁、明确的方法可以记录一致性,这样就不必显式地记录一致性语义?类似地,一种记录它的方法,让未来的用户知道他们可以利用只读的通用代码,但不希望变异算法起作用

如果我放松问题,使容器可赋值(但其元素不可赋值),我会得到什么?此时,
operator=
swap
是可能的,但是取消引用
iterator
仍然返回一个
const元素
Container
现在是否符合“Container”的条件

const std::list
容器的界面大致相同。这是否意味着它既不是“容器”,也不是“序列”

脚注(1)我有涵盖整个范围的用例。我有一个可能是容器类,它适应一些只读数据,所以它必须是不可变的。我有一个可以根据需要生成自己内容的准容器,所以它是可变的,但不能按照STL要求的方式替换元素。我还有另一个可能是容器,它以某种方式存储其元素,使得
insert()
的速度太慢,永远不会有用。最后,我有一个字符串,它将文本存储在UTF-8中,同时公开面向代码点的接口;可变实现是可能的,但完全没有必要


脚注(2)这只是为了举例说明。我很确定
std::list
需要一个可分配的元素类型。

只要您的对象可以提供一个一致的常量迭代器,它就不必有任何其他内容。在容器类上实现这一点应该很容易


(如果适用,请查看Boost.Iterators库;它有iterator_facade和iterator_Adapter类来帮助您了解基本细节)

STL没有定义任何较小的概念;主要是因为
const
的概念通常是在每个迭代器或每个引用级别上表达的,而不是在每个类级别上

您不应该提供带有意外语义的
迭代器
,而应该只提供
常量迭代器
。这允许客户端代码在出错时在最符合逻辑的地方失败(具有最可读的错误消息)

可能最简单的方法是封装它并防止所有非常量别名

class example {
    std::list<sometype> stuff;
public:
    void Process(...) { ... }
    const std::list<sometype>& Results() { return stuff; }
};
类示例{
列出材料;
公众:
无效进程(…){…}
const std::list&Results(){return stuff;}
};

现在,任何客户机代码都确切地知道它们可以对结果的返回值做什么——需要变异的nada

如何将初始元素放入容器中?我的每个用例都有不同的方法。对于适配器,我得到了已经填充的适配容器,我的类只存储一个指向它的指针。自填充容器根据一些可变参数在请求时创建其元素。通用STL兼容插入太慢的容器具有高效的非STL兼容插入方法。UTF-8字符串只是在其构造函数中给定了一个字节数组或迭代器范围。显而易见的解决方案是使用迭代器,或将迭代器从可变容器移动到不可变的
容器中。使用分层B树进行结构共享如何?