如何使用initializer_list构造函数推导编译时矩阵类的二维?

问题描述 投票:0回答:1
#include <iostream>
#include <array>

template <typename T, size_t Rows, size_t Cols>
class Matrix {

protected:

    std::array<std::array<T, Cols>, Rows> matrix;

public:

    constexpr Matrix() = default;

    constexpr explicit Matrix(std::array<std::array<T, Cols>, Rows> matrix) : matrix(std::move(matrix)) { }

    consteval Matrix(std::initializer_list<std::initializer_list<T>> matrix) : matrix() {
        if (matrix.size() != Rows) {
            throw std::invalid_argument("Invalid matrix Rows count");
        }
        auto current_row = matrix.begin();
        for (size_t i = 0; i < matrix.size(); i++, current_row++) {
            if (current_row->size() != Cols) {
                throw std::invalid_argument("Invalid matrix column count");
            }
            std::copy(current_row->begin(), current_row->end(), this->matrix[i].begin());
        }
    }

    constexpr auto& operator[](this auto&& self, size_t index) { return self.matrix[index]; }
};

template <typename T, size_t N>
struct Vector : Matrix<T, 1, N> {
    using Matrix<T, 1, N>::Matrix;

    template <typename U, typename... Us>
    consteval explicit Vector(U u, Us... us) {
        this->matrix[0] = { u, us... };
    }

    constexpr auto& operator[](this auto&& self, size_t index) { return self.matrix[0][index]; }
};

template <typename T, typename... U>
Vector(T, U...) -> Vector<T, 1 + sizeof...(U)>;

int main() {
    constexpr Matrix<int, 4, 3> matrix {
        { 1, 2, 3 },
        { 1, 2, 3 },
        { 1, 2, 3 },
        { 1, 2, 3 }
    };
    static_assert(matrix[2][1] == 2);

    constexpr Vector v { 1, 2, 3 };
    static_assert(v[1] == 2);
}

在这里,为向量类编写推导指南以避免指定类型和元素数量是很容易的,但是当涉及到

Matrix
类时,这就相当具有挑战性了。这是因为传递的initializer_list的
std::initializer_list::size
不是常量表达式,我无法从中推导出
Cols
参数。

  1. 如何写出这样的表达式并推导出类型和维数?
    constexpr Matrix matrix {
        { 1, 2, 3 },
        { 1, 2, 3 },
        { 1, 2, 3 },
        { 1, 2, 3 }
    };
  1. 如何编写这样一个表达式并推导维度并将所包含元素的类型作为转换为传递类型的初始值设定项元素?
    constexpr Matrix<double> matrix {
        { 1, 2, 3 },
        { 1, 2, 3 },
        { 1, 2, 3 },
        { 1, 2, 3 }
    };
c++ matrix constexpr initializer-list compile-time
1个回答
0
投票

您可以添加数组的推导指南:

template <class T, size_t R, size_t C>
Matrix(const T(&arr)[R][C]) -> Matrix<T, R, C>;

...并且您需要一组额外的支架才能使用它:

constexpr Matrix matrix {{
    { 1, 2, 3 },
    { 1, 2, 3 },
    { 1, 2, 3 },
    { 1, 2, 3 }
}};
最新问题
© www.soinside.com 2019 - 2025. All rights reserved.