繁体   English   中英

模糊的构造函数调用(我假设)

[英]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}});

(注意: Matrix3x3TMatrixNxM <float,3,3>的typedef,并且它在Math名称空间中)

直到现在,它仍然有效,因为我并不总是拥有该数组构造函数,只有初始化器列出了一个。 但是现在,编译器甚至没有完成编译,它崩溃了 (我收到“停止工作”弹出窗口,必须关闭它,我使用的是MS VS Express 2013)

如果我这样做:

Math::Matrix3x3 b = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};

然后工作正常。 这是我的假设

当我这样做时,就不会有任何歧义,因为您只能以这种方式调用initializer_list构造函数。 对于第一种方法,编译器可能会感到困惑,因为array是聚合类型,这意味着初始化以双大括号开头,例如:{{...}},而且由于我有一个初始化列表,因此我必须使用double括号。 但是,这真的是一个问题吗,因为我从未真正使用过大括号,所以这些都是大括号内的单括号列表?

这里真正发生了什么,我该如何解决这个问题?

感谢您的时间!

编辑

如果我让构造函数通过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;
}

如果用数组注释掉构造函数的声明/定义,那么它应该可以编译并很好地执行。 如前所述,我正在使用MS VS Express 2013中的编译器。

好吧,看来它不适用于Microsoft的编译器。 我试图在使用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}}  }});

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM