Вывести из параметров конструктора только часть параметров шаблона класса, а остальное указать самому
Есть шаблонный класс (многомерная матрица), у которой есть конструктор, принимающий набор целых аргументов(размеры матрицы по разным осям). Если при инициализации экземпляра указать параметры матрицы полностью (тип значений, хранящихся в контейнере, и размерность), всё, конечно же, работает.
#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 шт):
Навскидку придумалось что-то вроде
.....
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...()
создать, но как туда данные записать...