2017-02-16 60 views
3

我在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}} - 是 '矩阵'对象,但如何?

+0

@AnT,是的,因为我有载体向量。我甚至可以输入{{1,2,3},{1,2},{1}}并将其编译。 –

+0

@安,是的,我的错,谢谢。 –

+0

'{1}'是'矢量','{{1},{1}}'是'std :: vector >'。如果你删除你的第一个构造函数,代码仍然应该编译。 –

回答

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

+0

但是为什么它试图将这个({{1},{1}})结构转换成一个“矩阵”?这是结构如何工作?在此之前,我只使用了类并从未遇到过这个问题。 –

+0

你告诉过它!像'mat m(EXPRESSION)'这样的任何语句都要求编译器从'EXPRESSION'创建一个新的'mat'。对于结构体和类都是一样的,如果你把你的结构变成一个类(只要确保一切都是公开的),这些都不会改变。 – Useless

+0

@Useless:你应该提及'{{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. 尝试通过使用matrix(const matrix&)构建从临时mat

打标头(或两者)构造函数(S)为explicit将毫不含糊地让matrix mat({{1},{1}})调用...

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

...之一。

wandbox example

+0

'隐含地用第一个构造函数创建一个临时矩阵,它意味着{{m},{n}}变成m,n? –

+1

@ VladMarkushin:从这里的输出可以清楚看到:http://melpon.org/wandbox/permlink/6qfAZ5Y7It0k5OJE - 基本上,是的。 –

+1

@ VladMarkushin:我更新了答案 - 现在清楚了吗? –