我有这个矩阵类,它分配堆上的数据和一个辅助类M,它是一个矩阵,数据作为c风格数组,没有分配。模板参数推导自动适用于helper类。但不适合矩阵类
我可以用模板参数推导构造一个矩阵:
M m{{{1, 2}, {3, 4}}};
Matrix a{M{{{1, 2}, {3, 4}}}};
我要找的是摆脱助手类,所以下面的工作:
Matrix a{{{1, 2}, {3, 4}}};
下面是一个使用helper类的工作示例:https://godbolt.org/z/46vEqbvax
#include <cstddef>
#include <type_traits>
#include <cstring>
#include <initializer_list>
#include <utility>
#include <memory>
#include <cassert>
#include <algorithm>
template <typename T, std::size_t rows, std::size_t cols>
class M {
public:
const T * operator[](std::size_t x) const {
return data[x];
}
T * operator[](std::size_t x) {
return data[x];
}
T data[rows][cols]{};
};
template <typename T, std::size_t rows, std::size_t cols>
class Matrix {
private:
T *data{new T[rows * cols]};
public:
Matrix() { }
~Matrix() {
delete[] data;
data = nullptr; // crash on use after free
}
Matrix(const Matrix &other) {
*this = other;
}
Matrix(T &&other) : data(other.data) {
other.data = nullptr;
}
Matrix & operator=(const Matrix &other) {
if constexpr (std::is_aggregate_v<T>) {
memcpy(data, other.data, sizeof(T) * rows * cols);
} else {
for (std::size_t i = 0; i < rows; ++i) {
for (std::size_t j = 0; j < cols; ++j) {
(*this)[i][j] = other[i][j];
}
}
}
return *this;
}
Matrix operator=(Matrix &&other) {
swap(data, other.data);
return *this;
}
const T * operator[](std::size_t x) const {
return &data[x * cols];
}
T * operator[](std::size_t x) {
return &data[x * cols];
}
Matrix(const M<T, rows, cols>& other) {
if constexpr (std::is_aggregate_v<T>) {
memcpy(data, other.data, sizeof(T) * rows * cols);
} else {
for (std::size_t i = 0; i < rows; ++i) {
for (std::size_t j = 0; j < cols; ++j) {
(*this)[i][j] = other[i][j];
}
}
}
}
Matrix(M<T, rows, cols>&& other) {
if constexpr (std::is_aggregate_v<T>) {
memcpy(data, other.data, sizeof(T) * rows * cols);
} else {
for (std::size_t i = 0; i < rows; ++i) {
for (std::size_t j = 0; j < cols; ++j) {
std::swap((*this)[i][j], other[i][j]);
}
}
}
}
};
//template <typename T, std::size_t rows, std::size_t cols>
//Matrix(M<T, rows, cols>) -> Matrix<T, rows, cols>;
#include <iostream>
int main() {
Matrix a{M{{{1, 2}, {3, 4}}}};
Matrix b{a};
std::cout << b[0][0] << " " << b[0][1] << std::endl;
std::cout << b[1][0] << " " << b[1][1] << std::endl;
}
您可以摆脱辅助类M
,并通过将构造函数参数的类型更改为(l-值和r-值引用)c风格数组来自动推导Matrix
模板参数:
//Matrix(const M<T, rows, cols>& other) {
Matrix(const T (&other)[rows][cols]) {
// ... same implementation ...
}
//Matrix(M<T, rows, cols>&& other) {
Matrix(T (&&other)[rows][cols]) {
// ... same implementation ...
}
演示