Eigen 对 Rows 模板的可变模板扩展有问题

Eigen having issues with variadic template expansion of the Rows template

我正在尝试创建一个使用 Eigen:Matrix 的网格;图书馆见 here

那么让我们看一下最小的代码:

template<typename Types, int... Sizes> class Grid;

template<typename... Types, int... Sizes>
class Grid<std::tuple<Types...>, Sizes...>
{
public:
    using grid_type = std::tuple<Eigen::Matrix<Types, Sizes, 1>...>;
};

然后在main,例如:

Grid<std::tuple<long, int>, -1, 10000>::grid_type;

我在VS2017编译时出现如下三个错误:

Error C3548 '_Rows': parameter pack cannot be used in this context

Error C2976 'Eigen::Matrix': too few template arguments

Error C3546 '...': there are no parameter packs available to expand

Error C3203 'Matrix': unspecialized class template can't be used as a template argument for template parameter '_Types', expected a real type

现在,如果我们改用 std::array 之类的东西,那么即使使用 -1 参数,一切都很好(它只是转换为正数 size_t):

using grid_type = std::tuple<std::array<Types, Sizes>...>;

grid_type 如期而至。

奇怪的是,VS的intellisense可以正确判断Eigen版本,但是编译不了...

好的,我明白了。因为 Eigen::Matrix 使用某些构造函数参数的默认值,在本例中依赖于 Rows/Cols 参数(其中 Rows 是可变参数模板),所以编译器会感到困惑。我明确列出了所有参数,并编译:

using grid_type = std::tuple<Eigen::Matrix<Types, Sizes, 1, Eigen::AutoAlign | false, Sizes,1>...>;

然而,这仍然不能满足我,因为奇怪的是智能感知可以处理这个但编译器不能。

确实,使用 GCC、clang 和 ICC 可以很好地编译,但不能使用 MSVC。这是 MSVC 的更好解决方法:

template<typename Scalar,int Rows>
using Mat = Eigen::Matrix<Scalar, Rows, 1>;

using grid_type = std::tuple<Mat<Types,Sizes>...>;