Search code examples
c++language-lawyertemplate-argument-deduction

Should the order of template arguments matter when they are all deduced?


I'm getting a discrepancy between Clang, GCC and MSVC, where GCC and Clang do what I expect:

#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);
}

MSVC won't compile that but GCC and Clang will.

Is this an MSVC bug? MSVC says:

<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

But if I try other orders of template arguments (as indicated by "OK" and "Bad" comments), it accepts some orders.


Solution

  • This is a bug in MSVC. I have filed a bug report to Microsoft.

    Its was closed as a duplicate which is expected to be fixed in VS 2022 v17.7 (MSVC 19.36).

    Thanks to Ben for discovering and to Ted Lyngmo and 273K for analyzing it in the comments!