В своем проекте я изменил используемый тип точки с 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.
Как было предложено в утверждении-сообщении, я прочитал о необходимом выравнивании векторизуемых объектов Eigen фиксированного размера. А также подраздел о контейнерах STL. И похоже, что у меня есть два варианта:
- используйте
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
?- Is this because of alignment?
- Можно ли как-то выровнять список инициализаторов?
Почему версия специализации не работает?
- Are these lacking the initializer list feature?