使用初始值设定项列表作为参数时存在歧义
Ambiguity when using initializer list as parameter
我对以下代码感到困惑:
#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)
{ ... }
该构造函数和vector
的initializer_list
构造函数在函数调用f({x, y});
中都是同样好的匹配,导致了歧义错误。
下面是一个使用类似构造函数和函数调用的虚构示例,它也会导致歧义错误。
相关文章:
- C++17 中的歧义错误(模板模板参数和默认参数问题)
- 关于模板化函数上传递的右值引用和传递的参数的歧义
- C++ 显式多参数构造函数歧义
- variadic模板歧义 - 空参数包
- 函数调用带有指针、引用和常量引用参数的歧义
- 如何在C++中消除一个可变参数函数与另一个可变参数函数的歧义
- 更改专用化"template<...>"行中模板参数的顺序是否会导致定义重复或歧义?
- 使用默认参数消除函数的歧义
- 函数参数绑定的完美转发和歧义
- 可变参数模板、参数包及其在参数列表中讨论的歧义
- 使用初始值设定项列表作为参数时存在歧义
- 可变类型的部分模板专门化和扩展到外部类型的可变参数包会导致歧义
- C++11:在按值传递参数初始化时转换构造函数和转换函数之间的歧义
- 采用可选且无参数的重载方法:为什么没有歧义
- 消除作为模板参数传递的重载成员函数指针的歧义
- C++11参数子句中声明符和抽象声明符之间的歧义
- 当添加模板参数时,重载解析会产生歧义调用
- 绕过依赖于参数的查找歧义的非侵入性方法
- 模板参数为模板歧义符号
- 如何消除具有相同模板参数名称的模板类的两个实例的歧义