Eigen  3.4.90 (git rev a4098ac676528a83cfb73d4d26ce1b42ec05f47c)
Using STL Containers with Eigen

# Executive summary

If you're compiling in [c++17] mode only with a sufficiently recent compiler (e.g., GCC>=7, clang>=5, MSVC>=19.12), then everything is taken care by the compiler and you can stop reading.

Otherwise, using STL containers on fixed-size vectorizable Eigen types, or classes having members of such types, requires the use of an over-aligned allocator. That is, an allocator capable of allocating buffers with 16, 32, or even 64 bytes alignment. Eigen does provide one ready for use: aligned_allocator.

Prior to [c++11], if you want to use the std::vector container, then you also have to  #include <Eigen/StdVector> .

These issues arise only with fixed-size vectorizable Eigen types and structures having such Eigen objects as member. For other Eigen types, such as Vector3f or MatrixXd, no special care is needed when using STL containers.

# Using an aligned allocator

STL containers take an optional template parameter, the allocator type. When using STL containers on fixed-size vectorizable Eigen types, you need tell the container to use an allocator that will always allocate memory at 16-byte-aligned (or more) locations. Fortunately, Eigen does provide such an allocator: Eigen::aligned_allocator.

std::map<int, Eigen::Vector4d>

you need to use

std::map<int, Eigen::Vector4d, std::less<int>,
STL compatible allocator to use with types requiring a non-standard alignment.
Definition: Memory.h:874

Note that the third parameter std::less<int> is just the default value, but we have to include it because we want to specify the fourth parameter, which is the allocator type.

# The case of std::vector

This section is for c++98/03 users only. [c++11] (or above) users can stop reading here.

So in c++98/03, the situation with std::vector is more complicated because of a bug in the standard (explanation below). To workaround the issue, we had to specialize it for the Eigen::aligned_allocator type. In practice you must use the Eigen::aligned_allocator (not another aligned allocator), and #include <Eigen/StdVector>.

Here is an example:

#include<Eigen/StdVector>
/* ... */
std::vector<Eigen::Vector4f,Eigen::aligned_allocator<Eigen::Vector4f> >

Explanation: The resize() method of std::vector takes a value_type argument (defaulting to value_type()). So with std::vector<Eigen::Vector4d>, some Eigen::Vector4d objects will be passed by value, which discards any alignment modifiers, so a Eigen::Vector4d can be created at an unaligned location. In order to avoid that, the only solution we saw was to specialize std::vector to make it work on a slight modification of, here, Eigen::Vector4d, that is able to deal properly with this situation.

## An alternative - specializing std::vector for Eigen types

As an alternative to the recommended approach described above, you have the option to specialize std::vector for Eigen types requiring alignment. The advantage is that you won't need to declare std::vector all over with Eigen::aligned_allocator. One drawback on the other hand side is that the specialization needs to be defined before all code pieces in which e.g. std::vector<Vector2d> is used. Otherwise, without knowing the specialization the compiler will compile that particular instance with the default std::allocator and you program is most likely to crash.

Here is an example:

#include<Eigen/StdVector>
/* ... */
EIGEN_DEFINE_STL_VECTOR_SPECIALIZATION(Matrix2d)
std::vector<Eigen::Vector2d>
The matrix class, also used for vectors and row-vectors.
Definition: Matrix.h:182