В моем проекте я изменил используемый тип точки от Eigen::Vector2f
до Eigen::Vector2d
и столкнулся с проблемой выравнивания.
Вот упрощенная версия кода:
#include <vector>
#include <Eigen/Eigen>
int main()
{
std::vector<Eigen::Vector2d> points = { {0,0}, {0,1} };
}
Я получаю следующую ошибку времени выполнения:
eigen3/Eigen/src/Core/DenseStorage.h:78: Eigen::internal::plain_array<double, 2, 0, 16>::plain_array() [T = double, Size = 2, MatrixOrArrayOptions = 0, Alignment = 16]: Assertion `(reinterpret_cast<size_t>(array) & 0xf) == 0 && "this assertion is explained here: " "http://eigen.tuxfamily.org/dox-devel/group__TopicUnalignedArrayAssert.html" " **** READ THIS WEB PAGE !!! ****"' failed.
В качестве предложения assert-сообщения я прочитал о требуемом выравнивании объектов Eigen с фиксированным размером. А также подраздел о STL Containers. И похоже, что у меня есть два варианта:
- используйте
Eigen::aligned_allocator
- или используйте макрос
EIGEN_DEFINE_STL_VECTOR_SPECIALIZATION
.
Обе попытки не компилируются (протестированы с помощью GCC 4.8.3 и Clang 3.5), потому что компилятор не может правильно преобразовать список инициализаторов.
Здесь измененный код:
#include <vector>
#include <Eigen/Eigen>
#include <Eigen/StdVector>
// EIGEN_DEFINE_STL_VECTOR_SPECIALIZATION(Eigen::Vector2d)
int main()
{
std::vector<Eigen::Vector2d, Eigen::aligned_allocator<Eigen::Vector2d>> points = { {0,0}, {0,1} };
// std::vector<Eigen::Vector2d> points = { {0,0}, {0,1} };
}
Выход ошибки GCC:
error: could not convert ‘{{0, 0}, {0, 1}}’ from ‘<brace-enclosed initializer list>’ to ‘std::vector<Eigen::Matrix<double, 2, 1>, Eigen::aligned_allocator<Eigen::Matrix<double, 2, 1> > >’
Итак, мне интересно:
-
Почему списки инициализаторов недоступны при смене распределителя
std::vector
?- Это из-за выравнивания?
- Можно ли каким-либо образом выровнять список инициализаторов?
-
Почему версия специализации не работает?
- У них отсутствует функция списка инициализаторов?