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

How to handle mixing of different libraries (eg. stl and eigen3) that use different types for indices (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);
}

这里我得到了编译器警告:

warning: implicit conversion loses integer precision: 'const size_t' (aka 'const unsigned long') to 'int'

所以我当然可以在所有出现这种情况的函数中加一个static_cast<int>(i),但我想知道是否有更好的方法来处理这种情况。我想这也发生在许多其他 "library-mixing" 身上。

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

可能还值得研究一下 Eigen 如何定义其索引类型。特别是 you are allowed to redefine it if necessary, by changing a preprocessor directive,通过 #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 提供的额外范围,我认为您的 Eigen 设置提供的索引类型稍微更适合手头的任务。

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

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