Move semantics and placement insertion are two features brought by C++11
containers that can have a very positive impact in your C++ applications.
Boost.Container implements both techniques both for C++11 and C++03 compilers.

All containers offered by Boost.Container
can store movable-only types and actual requirements for value_type depend on each container operations.
Following C++11 requirements even for C++03 compilers, many operations
now require movable or default constructible types instead of just copy
constructible types.

Containers themselves are also movable, with no-throw guarantee if allocator
or predicate (if present) copy operations are no-throw. This allows high
performance operations when transferring data between vectors. Let's see
an example:

#include<boost/container/vector.hpp>#include<boost/move/utility_core.hpp>#include<cassert>//Non-copyable classclassnon_copyable{BOOST_MOVABLE_BUT_NOT_COPYABLE(non_copyable)public:non_copyable(){}non_copyable(BOOST_RV_REF(non_copyable)){}non_copyable&operator=(BOOST_RV_REF(non_copyable)){return*this;}};intmain(){usingnamespaceboost::container;//Store non-copyable objects in a vectorvector<non_copyable>v;non_copyablenc;v.push_back(boost::move(nc));assert(v.size()==1);//Reserve no longer needs copy-constructiblev.reserve(100);assert(v.capacity()>=100);//This resize overload only needs movable and default constructiblev.resize(200);assert(v.size()==200);//Containers are also movablevector<non_copyable>v_other(boost::move(v));assert(v_other.size()==200);assert(v.empty());return0;}

All containers offered by Boost.Container
implement placement insertion, which means that objects can be built directly
into the container from user arguments without creating any temporary object.
For compilers without variadic templates support placement insertion is
emulated up to a finite (10) number of arguments.

#include<boost/container/list.hpp>#include<cassert>//Non-copyable and non-movable classclassnon_copy_movable{non_copy_movable(constnon_copy_movable&);non_copy_movable&operator=(constnon_copy_movable&);public:non_copy_movable(int=0){}};intmain(){usingnamespaceboost::container;//Store non-copyable and non-movable objects in a listlist<non_copy_movable>l;non_copy_movablencm;//A new element will be built calling non_copy_movable(int) contructorl.emplace(l.begin(),0);assert(l.size()==1);//A new element will be value initializedl.emplace(l.begin());assert(l.size()==2);return0;}

Incomplete types allow type erasure and recursive data types, and C and C++ programmers
have been using it for years to build complex data structures, like tree
structures where a node may have an arbitrary number of children.

“Unlike most of my columns, this one is about something you
can't do with the C++ Standard library: put incomplete types in one of the
standard containers. This column explains why you might want to do this,
why the standardization committee banned it even though they knew it was
useful, and what you might be able to do to get around the restriction.”

“In 1997, shortly before the C++ Standard was completed,
the standardization committee received a query: Is it possible to create
standard containers with incomplete types? It took a while for the committee
to understand the question. What would such a thing even mean, and why on
earth would you ever want to do it? The committee eventually worked it out
and came up with an answer to the question. (Just so you don't have to skip
ahead to the end, the answer is "no.") But the question is much
more interesting than the answer: it points to a useful, and insufficiently
discussed, programming technique. The standard library doesn't directly support
that technique, but the two can be made to coexist.”

“In a future revision of C++, it might make sense to relax
the restriction on instantiating standard library templates with incomplete
types. Clearly, the general prohibition should stay in place - instantiating
templates with incomplete types is a delicate business, and there are too
many classes in the standard library where it would make no sense. But perhaps
it should be relaxed on a case-by-case basis, and vector
looks like a good candidate for such special-case treatment: it's the one
standard container class where there are good reasons to instantiate it with
an incomplete type and where Standard Library implementors want to make it
work. As of today, in fact, implementors would have to go out of their way
to prohibit it!”

C++11 standard is also cautious about incomplete types and STL: “17.6.4.8
Other functions (...) 2. the effects are undefined in the following cases:
(...) In particular - if an incomplete type (3.9) is used as a template argument
when instantiating a template component, unless specifically allowed for
that component”.

Fortunately all Boost.Container containers
except static_vector
and basic_string
are designed to support incomplete types. static_vector
is special because it statically allocates memory for value_type
and this requires complete types and basic_string
implements Small String Optimization which also requires complete types.

Boost.Container containers supporting incomplete
types also support instantiating iterators to those incomplete elements.

Containers of incomplete types are useful to break header file dependencies
and improve compilation types. With Boost.Container, you can write a header
file defining a class with containers of incomplete types as data members,
if you carefully put all the implementation details that require knowing
the size of the value_type
in your implementation file:

In this header file we define a class (MyClassHolder) that holds a vector
of an incomplete type (MyClass)
that it's only forward declared.

//MyClassHolder.cpp#include"MyClassHolder.h"//In the implementation MyClass must be a complete//type so we include the appropriate header#include"MyClass.h"voidMyClassHolder::AddNewObject(constMyClass&o){vector_.push_back(o);}constMyClass&MyClassHolder::GetLastObject()const{returnvector_.back();}

The paper N2913, titled SCARY
Iterator Assignment and Initialization, proposed a requirement that
a standard container's iterator types have no dependency on any type argument
apart from the container's value_type,
difference_type, pointertype,
and const_pointer type. In
particular, according to the proposal, the types of a standard container's
iterators should not depend on the container's key_compare,
hasher, key_equal,
or allocator types.

That paper demonstrated that SCARY operations were crucial to the performant
implementation of common design patterns using STL components. It showed
that implementations that support SCARY operations reduce object code bloat
by eliminating redundant specializations of iterator and algorithm templates.

Boost.Container containers implement SCARY
iterators so the iterator type of a container is only dependent on the allocator_traits<allocator_type>::pointer type (the pointer type of the
value_type to be inserted
in the container). Reference types and all other typedefs are deduced from
the pointer type using the C++11 pointer_traits
utility. This leads to lower code bloat in algorithms and classes templated
on iterators.