Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

A mutable container of immutable objects in C++

Tags:

c++

I'd like to have something equivalent to a C++ std::vector, where the underlying objects are immutable. So I can push_back() items to add them to the vector, etc. An actual std::vector maintains an array underneath that's bigger than the size of the vector, filled with default constructed objects, and when you push_back(), it does an assignment to an element in the array. My immutable objects don't have a default constructor, and assignment is a mutating operation, so that's out too.

I can do a vector<boost::optional<T>>, but that's a messy interface because I only want to put validly constructed objects into the vector, and only get those out of the vector.

I thought boost had something like this, but I couldn't find it. Does something like this exist?

like image 608
Martin C. Martin Avatar asked Dec 03 '14 19:12

Martin C. Martin


People also ask

What is mutable and immutable in C?

Mutable and immutable are English words meaning "can change" and "cannot change" respectively. The meaning of the words is the same in the IT context; i.e. a mutable string can be changed, and. an immutable string cannot be changed.

What is mutable object and immutable object?

Objects whose value can change are said to be mutable; objects whose value is unchangeable once they are created are called immutable.

What is mutable immutable datatypes?

Python Mutable data types are those whose values can be changed in place whereas Immutable data types are those that can never change their value in place.

What is mutable and immutable objects give examples?

Simple put, a mutable object can be changed after it is created, and an immutable object can't. Objects of built-in types like (int, float, bool, str, tuple, unicode) are immutable. Objects of built-in types like (list, set, dict) are mutable. Custom classes are generally mutable.


1 Answers

Your conception of how the vector works is incorrect.

The vector uses the allocator to allocate raw memory. That raw memory does not contain default constructed objects--it's just raw memory.

When you do a push_back (for example) it then uses a placement new to construct an object into the raw memory. Likewise, when you erase an object, it will end up directly invoking its destructor to turn the object back into raw memory.

With a current (C++11 or later) implementation of std::vector, your object doesn't need to support default construction or assignment. Supporting move construction and move assignment should be sufficient. To put them to use, you'd want to use emplace_back instead of push_back though.

like image 153
Jerry Coffin Avatar answered Oct 01 '22 00:10

Jerry Coffin