我正在尝试编写一个将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'
我的问题:
- 错误消息中的这个奇怪
|_Rows==&&?:&&_Rows!=?:
是什么? - 我该怎么做才能编译上面的代码?
bar
函数应具有T
和dim
可用性。我不能只接受const AnyType& arg1
,因为bar
的实际实现取决于编译时已知值T
和dim
。
我见过 https://eigen.tuxfamily.org/dox/TopicFunctionTakingEigenTypes.html。我想我明白他们在说什么,但我不确定它是否适用于这里。我把实际的Eigen::Vector
当作一个论据,而不是一个表达。
如果有表达方式,对我来说,实现它就好了。
但是,如果我尝试遵循他们的指示并仅使用ArrayBase<Derived>
,则会丢失有关T
和dim
的编译时信息。
这确实看起来像一个 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(可能可以进一步减少这一点(。