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.所以大小
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 {} {}
我遇到的问题是假设使用单个元素的数组初始化初始化整个数组而不是仅初始化第一个元素。
正如@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))...} {}
};