Ошибка: не удалось преобразовать <заключенный в скобки список инициализаторов> () из «<заключенный в скобки список инициализаторов>» в «struct» - PullRequest
1 голос
/ 20 марта 2019
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 Embedded Toolchain 8.2.1 и g++ -std=c++17 -O3 в качестве аргументов.

Ответы [ 2 ]

2 голосов
/ 20 марта 2019

Строк равно 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 голос
/ 20 марта 2019

Проблема, с которой я столкнулся, заключалась в том, что при инициализации массива с одним элементом инициализируется весь массив, а не только первый элемент.

Как предложил @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))...} {}
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...