使用初始值设定项列表作为参数时存在歧义

Ambiguity when using initializer list as parameter

本文关键字:参数 歧义 存在 列表      更新时间:2023-10-16

我对以下代码感到困惑:

#include <Eigen/Dense>
#include <vector>
class Foo {};
void f(Eigen::MatrixXd const &) {}
void f(std::vector<Eigen::MatrixXd> const &) {}
void g(Foo const &) {}
void g(std::vector<Foo> const &) {}
int main()
{
    Foo a, b, c;
    Eigen::MatrixXd x, y, z;
    // f({x, y}); ambiguity, why?!
    f({x, y, z}); // ok
    g({a,b}); // ok
    g({a,b,c}); // ok
}

如果我取消对main()中的第3行代码的注释,我会得到一个不明确的调用错误,

/Users/vlad/so.cpp: In function 'int main()':
/Users/vlad/so.cpp:17:13: error: call of overloaded 'f(<brace-enclosed initializer list>)' is ambiguous
     f({x, y}); //ambiguity, why?!
             ^
/Users/vlad/so.cpp:17:13: note: candidates are:
/Users/vlad/so.cpp:6:6: note: void f(const MatrixXd&)
 void f(Eigen::MatrixXd const &) {}
      ^
/Users/vlad/so.cpp:7:6: note: void f(const std::vector<Eigen::Matrix<double, -1, -1> >&)
 void f(std::vector<Eigen::MatrixXd> const &) {}

用init列表中的3个项目调用它是有效的。

然而,如果我不使用特征矩阵,而是使用我自己的类Foo(参见函数g),那么一切都很好。我完全不知道为什么在使用Eigen时评论的行是模糊的。有什么想法吗?

PS:如果我过载f,使其占用std::initializer_list<Eigen::MatrixXd>,那么问题就消失了,不再有模棱两可的调用。

错误很可能是由此构造函数模板引起的。

template<typename T0, typename T1>
EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE Matrix(const T0& x, const T1& y)
{ ... }

该构造函数和vectorinitializer_list构造函数在函数调用f({x, y});中都是同样好的匹配,导致了歧义错误。

下面是一个使用类似构造函数和函数调用的虚构示例,它也会导致歧义错误。