gpt4 book ai didi

c++ - 为什么更改 std::vector 的分配器时初始化列表不可用?

转载 作者:IT老高 更新时间:2023-10-28 22:28:22 25 4
gpt4 key购买 nike

在我的项目中,我将使用的点类型从 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.

正如断言消息所建议的,我读到了所需的 alignment of Fixed-size vectorizable Eigen objects .还有关于 STL Containers 的小节.看来我有两个选择:

  1. 使用 Eigen::aligned_allocator
  2. 或使用 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的分配器时初始化列表不可用?

    • 这是因为对齐吗?
    • 我能以某种方式对齐初始化列表吗?
  • 为什么特化版本失败了?

    • 这些是否缺少初始化列表功能?

最佳答案

在研究了 Eigen/StdVector 包含文件(准确地说是在 Eigen/src/StlSupport/StdVector.h line 68 of version 3.2.1 中)之后,似乎问题源于 std::vector 的部分模板特化 在这个头文件中。只要您使用 Eigen::aligned_allocator 作为分配器,这个部分模板特化就会替换 STL vector。而且这种特化似乎缺乏 C++11 的特性。

详细说明为什么除了替换分配器之外还需要这种特殊化:在 C++11 之前 resize function std::vector 可以采用附加参数按值初始化新创建的元素。 According to the Eigen3 Documentation按值传递参数会丢弃任何对齐修饰符,并且不能与固定大小的可矢量化 Eigen 对象一起使用(请参阅 SIMD)。

编辑:经过更多测试后,我意识到 std::vector 的 C++11 实现没有上述问题。因此,要解决对齐问题,您只需需要填写Eigen::aligned_allocator。但包含Eigen/StdVector。包含此文件将阻止您使用 std::vector 的 C++11 实现,因为此 header 定义了以 Eigen::aligned_allocator 作为分配器的部分特化。

关于c++ - 为什么更改 std::vector 的分配器时初始化列表不可用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24311357/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com