如何处理使用不同类型索引的不同库(例如 stl 和 eigen3)的混合(size_t、int、..)



>我有以下问题。我有一些使用 Eigen3 的代码。Eigen3 使用 int 或 long int 作为索引。在代码的某些点,我必须将特征数组的值存储在std::vector中。

下面是一些示例:

std::vector myStdVector;
Eigen::VectorXd myEigen;
....
for(size_t i=0; i<myStdVector.size(); i++)
{
myStdVector[i] = myEigen(i);
}

在这里,我收到编译器警告:

警告:隐式转换会丢失整数精度:"常量size_t" (又名"常量无符号长"(到"int">

因此,我当然可以为发生这种情况的所有函数添加static_cast<int>(i),但我想知道是否有更好的方法来处理此类事情。我想许多其他"库混合"也会发生这种情况。

在这种特定情况下,我建议使用较小容器的索引类型; 这将是 Eigen 的索引类型,由您的Eigen::VectorXd确定。 理想情况下,它将用作Eigen::Index,以实现向前兼容性。

可能还值得研究 Eigen 如何定义其索引类型。 特别是,如有必要,您可以通过更改预处理器指令、#define符号EIGEN_DEFAULT_DENSE_INDEX_TYPE来重新定义它;它默认为std::ptrdiff_t.

[但是请注意,在我自己的代码中,我通常更喜欢使用较大的索引(在本例中为size_t(,但要进行范围检查,就像使用较小的索引类型(如果适用((在本例中为Eigen::Index(一样。 然而,这只是个人喜好,并不一定是我认为最好的选择。


通常,在尝试选择最佳索引类型时,我建议您查看它们的可用范围。 首先,如果一个或多个潜在类型有符号,并且一个或多个有符号潜在类型允许负值*,则需要消除任何无符号类型,尤其是大于最大有符号类型的类型。 然后,您将查看您的用例,消除任何不适合您的预期目的的类型,并从剩余的潜在类型中选择最适合的类型。

具体而言,您希望将 Eigen3 容器中的值存储在 STL 容器中,其中 Eigen3 容器使用ptrdiff_t进行索引,并且(如您的评论中所述(据您所知仅使用非负索引值。 在这种情况下,任何一种都是可行的选择;ptrdiff_t提供的非负索引值的范围非常适合size_t的范围,循环条件将由您的VectorXd决定(因此也保证适合 Eigen3 容器的索引类型(。 因此,这两种潜在类型都是可行的选择。 由于目前不需要size_t提供的额外范围,因此我认为您的特征设置提供的索引类型更适合手头的任务。

*:虽然由于索引的工作方式,通常可以安全地假设索引值始终为正数,但我可以看到一些允许负值是有益的情况。 不过,这些通常很少见。

请注意,我假设示例代码中i<myStdVector.size()的循环条件是一个拼写错误,因为没有与初始描述或循环主体内执行的操作对齐。 如果我错了,那么这个决定就会变得更加复杂。

最新更新