1*bf2c3715SXin Linamespace Eigen { 2*bf2c3715SXin Li 3*bf2c3715SXin Li/** \eigenManualPage TopicStlContainers Using STL Containers with Eigen 4*bf2c3715SXin Li 5*bf2c3715SXin Li\eigenAutoToc 6*bf2c3715SXin Li 7*bf2c3715SXin Li\section StlContainers_summary Executive summary 8*bf2c3715SXin Li 9*bf2c3715SXin LiIf you're compiling in \cpp17 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. 10*bf2c3715SXin Li 11*bf2c3715SXin LiOtherwise, using STL containers on \ref TopicFixedSizeVectorizable "fixed-size vectorizable Eigen types", or classes having members of such types, requires the use of an over-aligned allocator. 12*bf2c3715SXin LiThat is, an allocator capable of allocating buffers with 16, 32, or even 64 bytes alignment. 13*bf2c3715SXin Li%Eigen does provide one ready for use: aligned_allocator. 14*bf2c3715SXin Li 15*bf2c3715SXin LiPrior to \cpp11, if you want to use the `std::vector` container, then you also have to <code> \#include <Eigen/StdVector> </code>. 16*bf2c3715SXin Li 17*bf2c3715SXin LiThese issues arise only with \ref TopicFixedSizeVectorizable "fixed-size vectorizable Eigen types" and \ref TopicStructHavingEigenMembers "structures having such Eigen objects as member". 18*bf2c3715SXin LiFor other %Eigen types, such as Vector3f or MatrixXd, no special care is needed when using STL containers. 19*bf2c3715SXin Li 20*bf2c3715SXin Li\section allocator Using an aligned allocator 21*bf2c3715SXin Li 22*bf2c3715SXin LiSTL containers take an optional template parameter, the allocator type. When using STL containers on \ref TopicFixedSizeVectorizable "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. 23*bf2c3715SXin Li 24*bf2c3715SXin LiFor example, instead of 25*bf2c3715SXin Li\code 26*bf2c3715SXin Listd::map<int, Eigen::Vector4d> 27*bf2c3715SXin Li\endcode 28*bf2c3715SXin Liyou need to use 29*bf2c3715SXin Li\code 30*bf2c3715SXin Listd::map<int, Eigen::Vector4d, std::less<int>, 31*bf2c3715SXin Li Eigen::aligned_allocator<std::pair<const int, Eigen::Vector4d> > > 32*bf2c3715SXin Li\endcode 33*bf2c3715SXin LiNote 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. 34*bf2c3715SXin Li 35*bf2c3715SXin Li\section StlContainers_vector The case of std::vector 36*bf2c3715SXin Li 37*bf2c3715SXin LiThis section is for c++98/03 users only. \cpp11 (or above) users can stop reading here. 38*bf2c3715SXin Li 39*bf2c3715SXin LiSo in c++98/03, the situation with `std::vector` is more complicated because of a bug in the standard (explanation below). 40*bf2c3715SXin LiTo workaround the issue, we had to specialize it for the Eigen::aligned_allocator type. 41*bf2c3715SXin LiIn practice you \b must use the Eigen::aligned_allocator (not another aligned allocator), \b and \#include <Eigen/StdVector>. 42*bf2c3715SXin Li 43*bf2c3715SXin LiHere is an example: 44*bf2c3715SXin Li\code 45*bf2c3715SXin Li#include<Eigen/StdVector> 46*bf2c3715SXin Li/* ... */ 47*bf2c3715SXin Listd::vector<Eigen::Vector4f,Eigen::aligned_allocator<Eigen::Vector4f> > 48*bf2c3715SXin Li\endcode 49*bf2c3715SXin Li 50*bf2c3715SXin Li<span class="note">\b 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. 51*bf2c3715SXin LiIn 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. 52*bf2c3715SXin Li</span> 53*bf2c3715SXin Li 54*bf2c3715SXin Li\subsection vector_spec An alternative - specializing std::vector for Eigen types 55*bf2c3715SXin Li 56*bf2c3715SXin LiAs an alternative to the recommended approach described above, you have the option to specialize std::vector for Eigen types requiring alignment. 57*bf2c3715SXin LiThe 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 58*bf2c3715SXin Lithe specialization needs to be defined before all code pieces in which e.g. `std::vector<Vector2d>` is used. Otherwise, without knowing the specialization 59*bf2c3715SXin Lithe compiler will compile that particular instance with the default `std::allocator` and you program is most likely to crash. 60*bf2c3715SXin Li 61*bf2c3715SXin LiHere is an example: 62*bf2c3715SXin Li\code 63*bf2c3715SXin Li#include<Eigen/StdVector> 64*bf2c3715SXin Li/* ... */ 65*bf2c3715SXin LiEIGEN_DEFINE_STL_VECTOR_SPECIALIZATION(Matrix2d) 66*bf2c3715SXin Listd::vector<Eigen::Vector2d> 67*bf2c3715SXin Li\endcode 68*bf2c3715SXin Li 69*bf2c3715SXin Li 70*bf2c3715SXin Li 71*bf2c3715SXin Li*/ 72*bf2c3715SXin Li 73*bf2c3715SXin Li} 74