2014-06-19 13 views
15

Trong dự án của tôi, tôi đã thay đổi loại điểm đã sử dụng từ Eigen::Vector2f thành Eigen::Vector2d và chạy vào vấn đề căn chỉnh.Tại sao các danh sách bộ khởi tạo không có sẵn khi thay đổi bộ cấp phát của std :: vector?

Đây là một phiên bản đơn giản của các mã:

#include <vector> 
#include <Eigen/Eigen> 

int main() 
{ 
    std::vector<Eigen::Vector2d> points = { {0,0}, {0,1} }; 
} 

Tôi nhận được lỗi thời gian chạy sau:

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. 

Khi assert-nhắn đề nghị, tôi đọc về các yêu cầu alignment of Fixed-size vectorizable Eigen objects . Và cũng là phần phụ về STL Containers. Và nó có vẻ như tôi có hai lựa chọn:

  1. sử dụng các Eigen::aligned_allocator
  2. hoặc sử dụng EIGEN_DEFINE_STL_VECTOR_SPECIALIZATION vĩ mô.

Cả hai lần thử không biên dịch (thử nghiệm với GCC 4.8.3 và Clang 3.5) vì trình biên dịch không thể chuyển đổi đúng danh sách khởi tạo.

Đây mã thay đổi:

#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 ra lỗi:

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> > >’ 

Vì vậy, tôi tự hỏi:

  • Tại sao là danh sách khởi tạo không có sẵn khi thay đổi bộ cấp phát của số std::vector?

    • Đây có phải là do căn chỉnh không?
    • Tôi có thể sắp xếp thứ tự danh sách khởi tạo bằng cách nào đó không?
  • Tại sao phiên bản chuyên môn không thành công?

    • Những tính năng này có thiếu tính năng danh sách khởi tạo không?

Trả lời

15

Sau khi nghiên cứu Eigen/StdVector bao gồm tập tin (để được chính xác nó là trong Eigen/src/StlSupport/StdVector.h line 68 of version 3.2.1), có vẻ như vấn đề bắt nguồn từ một mẫu đặc tả từng phần của std::vector trong tập tin tiêu đề này. Chuyên môn mẫu từng phần này thay thế cho STL vector ngay sau khi bạn sử dụng Eigen::aligned_allocator làm người cấp phát. Và chuyên môn này dường như thiếu các tính năng C++ 11.

Cụ thể tại sao chuyên môn hóa này là cần thiết ngoài việc thay thế bộ cấp phát: Trước khi C++ 11 resize function của std::vector có thể mất một tham số bổ sung bằng giá trị để khởi tạo các yếu tố mới được tạo ra. According to the Eigen3 Documentation truyền tham số theo giá trị loại bỏ bất kỳ công cụ điều chỉnh căn chỉnh nào và không thể sử dụng với các đối tượng Eigen có kích thước cố định (xem SIMD).

Edit: Sau một số thử nghiệm hơn tôi nhận ra rằng việc thực hiện C++ 11 của std::vector không có vấn đề đã nêu ở trên. Vì vậy, để giải quyết vấn đề căn chỉnh, bạn chỉ cần điền vào số Eigen::aligned_allocator. Nhưng không bao gồm Eigen/StdVector. Bao gồm tệp này sẽ ngăn bạn sử dụng triển khai C++ 11 của std::vector vì tiêu đề này xác định chuyên môn từng phần với Eigen::aligned_allocator làm người cấp phát.

Các vấn đề liên quan