模板参数均可推导时顺序是否重要?多编译器编译差异问询
MSVC模板参数推导的编译差异问题
问题场景
在Clang、GCC与MSVC编译器间存在如下编译差异,其中GCC与Clang的表现符合预期:
#include <Eigen/Core> template <typename Indices, typename T, int Rows> //< Bad //template <typename Indices, int Rows, typename T> //< OK //template <typename T, int Rows, typename Indices> //< OK //template <typename T, typename Indices, int Rows> //< Bad //template <int Rows, typename Indices, typename T> //< Bad //template <int Rows, typename T, typename Indices> //< Bad void f( const Eigen::Matrix<T, Rows, 1>&, const Indices& ) {} int main() { f(Eigen::Matrix<double, 6, 1>{}, 1); }
上述代码在GCC和Clang中可正常编译,但MSVC无法通过,报错信息如下:
<source>(16): error C2672: 'f': no matching overloaded function found <source>(9): note: could be 'void f(const Eigen::Matrix<T,Rows,1,0|_Rows==1&&false?Eigen::RowMajor:true&&_Rows!=1?Eigen::ColMajor:Eigen::ColMajor,_Rows,1> &,const Indices &)' <source>(16): note: 'void f(const Eigen::Matrix<T,Rows,1,0|_Rows==1&&false?Eigen::RowMajor:true&&_Rows!=1?Eigen::ColMajor:Eigen::ColMajor,_Rows,1> &,const Indices &)': could not deduce template argument for 'const Eigen::Matrix<T,Rows,1,0|_Rows==1&&false?Eigen::RowMajor:true&&_Rows!=1?Eigen::ColMajor:Eigen::ColMajor,_Rows,1> &' from 'Eigen::Matrix<double,6,1,0,6,1>' Compiler returned: 2
调整模板参数顺序后,标记为“OK”的参数顺序可让MSVC正常编译,标记为“Bad”的顺序仍会触发编译错误。
结论
这属于MSVC的模板参数推导实现Bug。根据C++标准,当所有模板参数都能通过函数实参推导得出时,模板参数的顺序不应该影响推导结果。
GCC和Clang的行为符合标准:它们能正确从Eigen::Matrix<double,6,1>推导出T=double、Rows=6,从第二个实参1推导出Indices=int,不受模板参数列表顺序的影响。
MSVC的问题在于,当非类型模板参数(如Rows)位于类型模板参数(如T)之后,或可推导的类型参数被其他可推导参数隔开时,无法正确完成模板参数的匹配推导,导致找不到匹配的函数重载。
内容的提问来源于stack exchange,提问作者Ben
相关产品推荐
相关产品推荐

