C ++相当于一个不可变的容器

时间:2016-02-20 03:47:24

标签: c++ collections immutability

最近的讨论让我想到了这个问题:

C ++中是否存在不可变容器?或者,由于C ++优先使用通用容器的迭代器,是否存在不可变迭代器?

我说的是类似于Guava ImmutableList或内置verifyNoMoreInteractions方法的东西。要明确的是,这两种类型的集合是非常不同的 - 前者本质上是不可变的,而后者只有获得不可修改引用的参与者不可变,但可能由可以访问未包装对象的参与者修改。

我很想知道是否存在与Collections.unmodifiable*相当的标准化(实际或事实上,如番石榴):

  • 任何演员都无法修改的集合。此外,采用此类型的函数提供的文档不能也不会修改作为参数接收的此类集合,或作为返回值返回。

ImmutableCollection(和相关方法):

  • 与上述完全不同,这是原始集合的视图,任何拥有ret ro = Colletions.unmodifiableCollection(orginalCollection)但没有返回值{{1}的任何人都可以修改}。通常,它是通过将原始集合包装在代理中来实现的,该代理可以阻止任何修改,但是其他实现也是可能的。

我很清楚originalCollection和朋友,但这是非常不同的 - 它确保调用者可以将对象传递给被调用者,并且对象不会修改它,但它不会向被调用者保证不会修改对象。

现在我在这里是一个长期的C ++用户,虽然不是在过去的5年里,但我无法想出明显的等价物。

2 个答案:

答案 0 :(得分:1)

有一个名为immer的项目可能可以满足这种需求:

“ C ++的不变和持久数据结构”

https://github.com/arximboldi/immer

答案 1 :(得分:-1)

不,C ++中没有这样的容器,但它真的容易在两个级别上执行此操作... 第一个正在const正确要存储的对象类,第二是使用const引用或指向所需容器的指针。例如:

#include <iostream>
#include <vector>
#include <string>
#include <memory>

using namespace std;

class Cow {
  public:
  Cow() : name("default") {}
  Cow(string Name) : name(Name) {}

  string shout() const { return name; }

  private:
  string name;
};

int main() {
    vector<unique_ptr<const Cow>> mc;
    Cow mm("Lol");
    mc.push_back(make_unique<const Cow>(Cow()));
    mc.push_back(make_unique<const Cow>(Cow("haha")));
    mc.push_back(make_unique<const Cow>(mm));

    const auto& mcc = mc;  //here, your immutable reference

    for(auto& x : mcc)
        cout << x.get()->shout() << " - - ";
    return 0;
}

我在这里使用std::unique_ptr,因为使用vector<const Cow> mc几乎肯定没用。

此部分const auto& mcc = mc;从此处开始,将mcc 作为您的不可变容器...您无法通过任何合法方式添加或修改其元素,除了导致失去const ......

这适用于我所知道的所有其他容器。

仍在Stackoverflow上,请参阅Immutable C++ container classImmutable container with mutable content

附注:另外,如果要使用的类const不正确,请创建一个const正确的廉价包装类,然后使用包装器。