如何在 constexpr 构造函数中初始化矩阵 ONCE?
How to initialize a matrix ONCE in a constexpr constructor?
我有以下矩阵class:
template<size_t Rows, size_t Cols>
class matrix
{
float data[Rows][Cols];
public:
constexpr matrix(const float (&input)[Rows][Cols]) : data{}
{
for (size_t i = 0; i < Rows; ++i)
std::copy(input[i], input[i] + Cols, data[i]);
}
};
用法:
constexpr auto m = matrix({
{4.3f, 5.0f, 1.2f},
{8.0f, 1.9f, 6.5f},
{9.1f, 2.2f, 3.7f},
});
This compiles(在 C++20 中)并且工作正常,但它需要初始化 data
两次。第一个 data{}
是必需的,因为所有内容都必须在 constexpr
构造函数中进行成员初始化,第二个复制实际输入。
在编译时初始化两次并不重要,但这也意味着此构造函数不能在 运行 时使用,因为它不必要地初始化相同的数据两次。
是否有与此伪代码等效的内容?
constexpr matrix(const float (&input)[Rows][Cols])
{
for (size_t i = 0; i < Rows; ++i)
std::constexpr_uninitialized_copy(input[i], input[i] + Cols, data[i]);
}
P1331(允许在 constexpr 上下文中进行简单的默认初始化)用于 C++20。它删除了以下要求:
every non-variant non-static data member and base class subobject shall be initialized
这就是要求您进行 : data {}
初始化的原因。
这应该行得通:
template<size_t Rows, size_t Cols>
class matrix
{
float data[Rows][Cols];
public:
constexpr matrix(const float (&input)[Rows][Cols])
{
for (size_t i = 0; i < Rows; ++i)
std::copy(input[i], input[i] + Cols, data[i]);
}
};
不再需要初始化 data
。
您可以使用 std::array
。唯一需要注意的是,您需要一对额外的大括号:
template<size_t Rows, size_t Cols>
class matrix
{
std::array<std::array<float, Rows>, Cols> data;
public:
constexpr matrix(std::array<std::array<float, Rows>, Cols> const& input) : data{input} {}
};
template<size_t Rows, size_t Cols>
matrix(const float (&input)[1][Rows][Cols]) -> matrix<Rows, Cols>;
int main()
{
constexpr auto m = matrix({{
{4.3f, 5.0f, 1.2f},
{8.0f, 1.9f, 6.5f},
{9.1f, 2.2f, 3.7f},
}});
}
如你所见,data
只初始化了一次
我有以下矩阵class:
template<size_t Rows, size_t Cols>
class matrix
{
float data[Rows][Cols];
public:
constexpr matrix(const float (&input)[Rows][Cols]) : data{}
{
for (size_t i = 0; i < Rows; ++i)
std::copy(input[i], input[i] + Cols, data[i]);
}
};
用法:
constexpr auto m = matrix({
{4.3f, 5.0f, 1.2f},
{8.0f, 1.9f, 6.5f},
{9.1f, 2.2f, 3.7f},
});
This compiles(在 C++20 中)并且工作正常,但它需要初始化 data
两次。第一个 data{}
是必需的,因为所有内容都必须在 constexpr
构造函数中进行成员初始化,第二个复制实际输入。
在编译时初始化两次并不重要,但这也意味着此构造函数不能在 运行 时使用,因为它不必要地初始化相同的数据两次。
是否有与此伪代码等效的内容?
constexpr matrix(const float (&input)[Rows][Cols])
{
for (size_t i = 0; i < Rows; ++i)
std::constexpr_uninitialized_copy(input[i], input[i] + Cols, data[i]);
}
P1331(允许在 constexpr 上下文中进行简单的默认初始化)用于 C++20。它删除了以下要求:
every non-variant non-static data member and base class subobject shall be initialized
这就是要求您进行 : data {}
初始化的原因。
这应该行得通:
template<size_t Rows, size_t Cols>
class matrix
{
float data[Rows][Cols];
public:
constexpr matrix(const float (&input)[Rows][Cols])
{
for (size_t i = 0; i < Rows; ++i)
std::copy(input[i], input[i] + Cols, data[i]);
}
};
不再需要初始化 data
。
您可以使用 std::array
。唯一需要注意的是,您需要一对额外的大括号:
template<size_t Rows, size_t Cols>
class matrix
{
std::array<std::array<float, Rows>, Cols> data;
public:
constexpr matrix(std::array<std::array<float, Rows>, Cols> const& input) : data{input} {}
};
template<size_t Rows, size_t Cols>
matrix(const float (&input)[1][Rows][Cols]) -> matrix<Rows, Cols>;
int main()
{
constexpr auto m = matrix({{
{4.3f, 5.0f, 1.2f},
{8.0f, 1.9f, 6.5f},
{9.1f, 2.2f, 3.7f},
}});
}
如你所见,data
只初始化了一次