Вывести из параметров конструктора только часть параметров шаблона класса, а остальное указать самому

Есть шаблонный класс (многомерная матрица), у которой есть конструктор, принимающий набор целых аргументов(размеры матрицы по разным осям). Если при инициализации экземпляра указать параметры матрицы полностью (тип значений, хранящихся в контейнере, и размерность), всё, конечно же, работает.

#include <vector>
#include <type_traits>
#include <concepts>

using dim_t = unsigned char;

template <typename type_, dim_t dimension_, class alloc_ = std::allocator<type_>>
class TMatrix {
public:

    using TData = std::vector<type_, alloc_>;
    using size_type = typename TData::size_type;

private:

    size_type size[dimension_];
    TData data;

protected:

    size_type CalcTotalSize() {
        auto res = size_type(1);
        for (auto& s : size) { res *= s; }
        return res;
    }

public:

    constexpr TMatrix() noexcept
        : size{}
        , data(1)
    {}

    template <std::integral ...size_types_>
        requires (sizeof...(size_types_) == dimension_)
    constexpr TMatrix(const size_types_&... sizes)
        : size{ static_cast<size_type>(sizes)... }
        , data(CalcTotalSize())
    {
    }

};

//template <typename type_, class alloc_ = std::allocator<type_>, std::integral ...size_types_>
//TMatrix(size_types_...) -> TMatrix<type_, sizeof...(size_types_), alloc_>;

int main()
{

    TMatrix<int, 6> M1(1, 2, 4, 6, 2, 2); // ок!
    //TMatrix<int> M2(1, 2, 4, 6, 2, 2); // хотелось бы, но нет :(

}

Но в принципе, набор аргументов конструктора, уже содержит нужную информацию о размерности - это количество аргументов. Но вот первый параметр (тип хранимых значений) всё равно нужно указывать. В связи с этим вопрос: Можно ли как-то заставить компилятор вывести только один параметр. а второй указать вручную? Короче, хочется объявлять переменные вот так:

    TMatrix<int> M2(1, 2, 4, 6, 2, 2);

Чтобы он сам понял, что имелось в виду TMatrix<int, 6>.

Пробовал через вот такую декларацию

template <typename type_, class alloc_ = std::allocator<type_>, std::integral ...size_types_>
TMatrix(size_types_...) -> TMatrix<type_, sizeof...(size_types_), alloc_>;

Но тут я даже сам не понял, что сделал


Ответы (1 шт):

Автор решения: Harry

Навскидку придумалось что-то вроде

.....
private:
    std::vector<size_type> size;
    TData data;
.....
template<std::integral ...size_types_>
constexpr TMatrix(const size_types_&... sizes)
    {
        (size.push_back(sizes),...);
        data = TData(CalcTotalSize());
    }

Особо в работоспособность не вдавался, но главная идея — внести параметры через fold expression. Может, можно и для массива, но я их плохо знаю, что-то не соображу, как именно. Сам-то массив можно через sizeof...() создать, но как туда данные записать...

→ Ссылка