以Eigen::Vector为参数

Taking Eigen::Vector as a parameter

我正在尝试编写一个将 Eigen::Vector<T, dim> 作为参数的函数。但是,以下示例无法编译:

#include <Eigen/Core>

template<class F, typename T, int dim>
void bar(F&& func, const Eigen::Vector<T, dim>& arg1) {
}

template<typename T, int dim>
void foo(const Eigen::Vector<T, dim>& a) {
  return bar([] {}, a);
}

int main() {
  Eigen::Vector<float, 3> v1{ 1.f,2.f,3.f };
  foo(v1);
  return 0;
}

这个,在 Visual Studio 2019 下,给我以下错误:

1>main.cpp(9,10): error C2672:  'bar': no matching overloaded function found
1>main.cpp(14): message :  see reference to function template instantiation 'void foo<float,3>(const Eigen::Matrix<float,3,1,0,3,1> &)' being compiled
1>main.cpp(9,1): error C2784:  'void bar(F &&,const Eigen::Matrix<T,dim,1,|_Rows==&&?:&&_Rows!=?:,_Rows,1> &)': could not deduce template argument for 'const Eigen::Matrix<T,dim,1,|_Rows==&&?:&&_Rows!=?:,_Rows,1> &' from 'const Eigen::Matrix<float,3,1,0,3,1>'
1>main.cpp(4): message :  see declaration of 'bar'

我的问题:

bar 函数应该有 Tdim 可用。我不能只采用 const AnyType& arg1,因为 bar 的实际实现取决于编译时已知值 Tdim.

我看过https://eigen.tuxfamily.org/dox/TopicFunctionTakingEigenTypes.html。我认为我明白他们在说什么,但我不确定它是否适用于这里。我将实际的 Eigen::Vector 作为参数,而不是表达式。

如果有一个表达对我来说很好,让它具体化。

然而,如果我尝试按照他们的指示使用 ArrayBase<Derived>,我会丢失有关 Tdim 的编译时信息。

这确实看起来像一个 MSVC 问题,它在 gcc >= 4.7 和 clang >= 3.5 下编译得很好:https://godbolt.org/z/kqoHyO

一种可能的解决方法是明确写出 Eigen::Vector 扩展为:

template<class F, typename T, int dim>
void bar(F&& func, const Eigen::Matrix<T, dim, 1, 0, dim, 1>& arg1) {
}

https://godbolt.org/z/vlvSDP

奇怪的 |_Rows==&&?:&&_Rows!=?: 看起来像 MSVC 破坏了 Options 模板参数的默认值:

          AutoAlign |
                      ( (_Rows==1 && _Cols!=1) ? Eigen::RowMajor
                      : (_Cols==1 && _Rows!=1) ? Eigen::ColMajor
                      : EIGEN_DEFAULT_MATRIX_STORAGE_ORDER_OPTION ),

如果你想弄清楚这个问题,你应该向 MSVC 维护者提交错误报告,也许可以使用像这样的简化示例:https://godbolt.org/z/U_0Sh7(可能会进一步减少这个问题).