不明确的构造函数调用(我认为)
Ambiguous constructor call (I assume)
我定义了一个矩阵类,如下所示:
template <typename T, unsigned int N, unsigned int M>
class TMatrixNxM //Rows x columns
{
public:
TMatrixNxM(T = T(0)); //Default constructor
TMatrixNxM(const std::array<std::array<T, M>, N>&); //Construct from array
TMatrixNxM(std::initializer_list<std::initializer_list<T>>); //Initializer
//...
private:
std::array<std::array<T, M>, N> data; //ROW-MAJOR
};
现在,在使用矩阵的代码中,我有:
Math::Matrix3x3 b({{1, 2, 3}, {4, 5, 6}, {7, 8, 9}});
(注意:Matrix3是TMatrixNxM<float,3,3>的typedef,它也在Math命名空间中)
到目前为止,它一直有效,因为我并不总是有那个数组构造函数,只有初始值设定项列表一个。但现在,编译器甚至还没有完成编译,它崩溃!(我得到"停止工作"弹出窗口,我必须关闭它,我正在使用MS VS Express 2013)
如果我这样做:
Math::Matrix3x3 b = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
然后它工作得很好。这就是我假设的:
当我这样做的时候,就没有歧义了,因为你只能用这种方式调用initializer_list构造函数。对于第一种方法,编译器可能会感到困惑,因为数组是一种聚合类型,这意味着初始化以双大括号开始,如:{{…}},但也因为我有一个初始化器列表的初始化器列表,所以我必须使用双大括号。但这真的是一个问题吗,因为我从来没有真正做过双括号,这些都是一个更大的单括号列表中的单括号的列表?
这里到底发生了什么?我该如何解决这个问题?
感谢您抽出时间!
编辑
如果我让构造函数通过const指针获取数组,编译器就不会崩溃了(因为我从来不会在构造函数调用中直接扑通数组,所以我有初始化器列表):
TMatrixNxM(const std::array<std::array<T, M>, N>*);
然而,有人能解释之前的实际问题是什么吗?我的假设是对的吗?
这里有一个可以用来测试的最小可编译(或者,好吧,不是)代码:
#include <array>
#include <initializer_list>
template <typename T, unsigned int N, unsigned int M>
class TMatrixNxM //Rows x columns
{
public:
TMatrixNxM(T = T(0));
TMatrixNxM(const std::array<std::array<T, M>, N>&);
TMatrixNxM(std::initializer_list<std::initializer_list<T>>);
private:
std::array<std::array<T, M>, N> data; //ROW-MAJOR
};
template <typename T, unsigned int N, unsigned int M>
TMatrixNxM<T, N, M>::TMatrixNxM(T par_value)
{
std::array<T, M> temp;
temp.fill(par_value);
data.fill(temp);
}
template <typename T, unsigned int N, unsigned int M>
TMatrixNxM<T, N, M>::TMatrixNxM(const std::array<std::array<T, M>, N> &par_values)
{
data = par_values;
}
template <typename T, unsigned int N, unsigned int M>
TMatrixNxM<T, N, M>::TMatrixNxM(std::initializer_list<std::initializer_list<T>> par_values)
{
int i = 0;
for(std::initializer_list<T> row : par_values)
{
int j = 0;
for(T value : row)
{
data[i][j] = value;
++j;
}
++i;
}
}
int main()
{
TMatrixNxM<float, 3, 3> b({{1, 2, 3}, {4, 5, 6}, {7, 8, 9}});
return 0;
}
如果用数组注释掉构造函数声明/定义,那么它应该编译并执行良好。如前所述,我使用的是MSVSExpress2013的编译器。
看起来它在微软的编译器上不起作用。我试着在使用GCC的Linux机器上编译相同的代码,它编译起来没有问题。它确实在按应该的方式调用初始值设定项列表构造函数。如果我在一个变量中创建一个数组并传递它,它也会编译得很好,它会调用数组构造函数:
std::array<float, 3> a = {{1, 2, 3}};
std::array<std::array<float, 3>, 3> b = {{a, a, a}};
TMatrixNxM<float, 3, 3> mat(b);
如果我直接初始化数组,它还会编译并调用数组构造函数:
TMatrixNxM<float, 3, 3> mat({{ {{1, 2, 3}}, {{4, 5, 6}}, {{7, 8, 9}} }});
- 父类的私有函数会导致对具有相同名称和相似参数的子类中的公共函数的不明确调用
- 调用'Node'构造函数是不明确的
- "fpclassify":对重载函数的不明确调用
- 为什么调用具有通用或 r 值引用的重载覆盖函数是不明确的?
- 如果存在具有不同参数的继承成员,为什么对 C++ 结构函数的调用不明确?
- 构建 castalia 时出错:重载函数的调用不明确
- 结构构造函数调用不明确
- 对没有参数的可变参数模板函数的不明确调用
- 对基类中重载函数的不明确调用
- 错误:对重载函数的调用不明确
- 对重载函数的不明确调用 - int 和 int>
- 对可变模板函数的调用不明确
- 为什么对重载函数的调用不明确
- C++中重载运算符函数对构造函数的调用不明确
- 为什么这些重载函数调用不明确
- 带有重载r值引用函数的调用不明确
- 如何避免对模板函数的调用不明确
- 为什么此函数调用不明确
- 由于超类(按值传递)导致重载构造函数调用不明确
- 为什么Google Mocks发现这个函数调用不明确