结构构造函数调用是不明确的

时间:2017-02-16 16:01:52

标签: c++ c++14

我在struct'matrix'中有2个构造函数。

matrix(const unsigned int m, const unsigned int n);
matrix(const std::vector<std::vector<double>> &elements);

当我这样称呼它时

matrix mat({{1},{1}});

抛出错误

call of overloaded ‘matrix(<brace-enclosed initializer list>)’ is ambiguous
note: candidate: matrix::matrix(const std::vector<std::vector<double> >&)
note: candidate: matrix::matrix(const matrix&)

所以,它认为,{{1},{1}} - 是'矩阵'对象,但是如何?

2 个答案:

答案 0 :(得分:4)

  

所以,它认为,{{1},{1}} - 是'矩阵'对象,但是如何?

在您的示例代码中

matrix mat({{1},{1}});

明确告诉编译器尝试将该表达式与matrix构造函数匹配。

它没有“认为”表达式{{1},{1}}是一个矩阵,它正试图将它组合成一个,因为你问过它。

至于为什么你得到错误(这不是你问的,但似乎值得一提),这是因为

vector<double> v{1};

是具有单个值(1.0)的向量的有效声明,因此

vector<vector<double>> vv{{1},{1}};

也是一个包含两个元素向量的向量的有效声明,每个元素向量都有一个值为1.0的double元素,最后

mat{{{1},{1}}};

将是向量构造函数的有效匹配。由于隐式允许这种转换,我们可以重写

mat m({{1},{1}});

作为

mat m(mat{{{1},{1}}});

因此含糊不清。请仔细注意圆形和花括号。

您可以使构造函数隐式,或者只是习惯于统一初始化样式并编写

mat m{{{1},{1}}};

首先。

答案 1 :(得分:3)

当调用matrix mat({{1},{1}})时,编译器会发现这两个不明确的构造路径:

  • 通过在向量中构造两个向量来调用vector<vector>>构造函数。

  • 使用第一个构造函数隐式创建临时矩阵,然后使用该临时构造mat

    1. matrix(const unsigned int m, const unsigned int n)创建临时矩阵。 (第一个{1}m匹配,第二个{1}n匹配。)

    2. 尝试使用mat从临时构建matrix(const matrix&)

将第一个(或两个)构造函数标记为explicit将明确地使matrix mat({{1},{1}})调用...

matrix(const std::vector<std::vector<double>> &elements);

...之一。

wandbox example