错误:无法将'<brace-包围的初始化程序=“” list =“”>()'从'<brace-包围的初始化程序=“” list =“”>'转换为'struct'

时间:2019-03-20 11:31:49

标签: c++ struct initialization g++ constexpr

template <typename T, unsigned int S>
class Vec
{
T data[S];

public:
    constexpr Vec(const T& s)
        : data{s} {}
};

template <typename T, unsigned int Rows, unsigned int Cols>
class Mat
{
    Vec<T, Cols> data[Rows];

public:
    constexpr Mat(const T& s)
        : data{Vec<T, Cols>(s)} {}
};

int main()
{
    constexpr Mat<double, 2, 2> m{1.0};
    return 0;
}

此代码给我以下错误:

source/main.cpp:24:25: error: could not convert '<brace-enclosed initializer list>()' from '<brace-enclosed initializer list>' to 'Vec<double, 2>'
   : data{Vec<T, Cols>(s)} {}
                         ^

有人能告诉我这个错误是什么意思,如何解决?我以前从未遇到过此错误。我使用GNU Arm嵌入式工具链8.2.1和g++ -std=c++17 -O3作为参数。

2 个答案:

答案 0 :(得分:2)

行是2。所以

Vec<T, Cols> data[Rows];

数据为2。但是data数组仅由一项初始化:

: data{Vec<T, Cols>(s)} {} 
       // initializer has only one element

因为您通过

提供了用户定义的构造函数
constexpr Vec(const T& s)
        : data{s} {}

Vec的默认构造函数被删除,并且data中的第二项无法构造。 添加默认的ctor:

constexpr Vec()
    :data {} {}

答案 1 :(得分:1)

我遇到的问题是,对单个元素使用数组初始化会初始化整个数组,而不是仅初始化第一个元素。

如@aschepler所建议,使用整数序列可修复编译器错误:

#include <utility>

template <typename T, unsigned int S>
class Vec
{
    std::array<T, S> data;

public:
    constexpr Vec(const T& s)
        : Vec(s, std::make_integer_sequence<unsigned int, S>{}) {}

private:
    template <unsigned int... Seq>
    constexpr Vec(const T& s, std::integer_sequence<unsigned int, Seq...>)
        : data{(static_cast<void>(Seq), s)...} {}
};

template <typename T, unsigned int Rows, unsigned int Cols>
class Mat
{
    std::array<Vec<T, Cols>, Rows> data;

public:
    constexpr Mat(const T& s)
        : Mat(s, std::make_integer_sequence<unsigned int, Rows>{}) {}

private:
    template <unsigned int... Seq>
    constexpr Mat(const T& s, std::integer_sequence<unsigned int, Seq...>)
        : data{(static_cast<void>(Seq), Vec<T, Cols>(s))...} {}
};