AlexanderBolshakov's blog

By AlexanderBolshakov, history, 8 years ago, In Russian

Я недавно решил закодить одну задачу, а т.к. я уже отучился от привычки использовать глобальные массивы с фиксированным размером, пришлось нагородить вот такую некрасивую штуку: vector<vector<vector<char>>> visited(n, vector<vector<char>>(n, vector<char>(n, false)));. Потом я вспомнил, что в современном C++ ничто не мешает сделать создание подобных векторов заметно более удобным, поэтому я реализовал вот это:

#include <vector>
#include <iostream>

template<typename T, size_t nDimensions>
struct VectorType
{
	typedef std::vector<typename VectorType<T, nDimensions - 1>::Type> Type;
};

template<typename T>
struct VectorType<T, 0>
{
	typedef T Type;
};

template<typename T>
struct MVector
{
	static typename VectorType<T, 0>::Type create();

	template<typename SizeType, typename... SizeTypes>
	static typename VectorType<T, 1 + sizeof...(SizeTypes)>::Type create(SizeType sz, SizeTypes... sizes);
};

template<typename T>
typename VectorType<T, 0>::Type MVector<T>::create()
{
	return typename VectorType<T, 0>::Type();
}


template<typename T>
template<typename SizeType, typename... SizeTypes>
typename VectorType<T, 1 + sizeof...(SizeTypes)>::Type MVector<T>::create(SizeType sz, SizeTypes... sizes)
{
	return typename VectorType<T, 1 + sizeof...(SizeTypes)>::Type(sz, create(sizes...));
}


int main()
{
	int n, m;
	std::cin >> n >> m;

	auto matrix = MVector<int>::create(n, m);

	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			std::cin >> matrix[i][j];
		}
	}

	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			std::cout << matrix[i][j] << " ";
		}
		std::cout << std::endl;
	}
}
»
8 years ago, # |
  Vote: I like it +5 Vote: I do not like it

This is pretty cool idea, but I'd suggest that you make support for default values with syntax like this:

MVector<int>(-1).create(n, m)

Also in C++14, you can simplify your current implementation quite a bit:

template<typename T>
T create_vec()
{
	return T();
}


template<typename T, class SizeT, class ...SizeTs>
auto create_vec(SizeT sz, SizeTs... sizes)
{
	return vector<decltype(create_vec<T>(sizes...))>(sz, create_vec<T>(sizes...));
}
  • »
    »
    8 years ago, # ^ |
      Vote: I like it 0 Vote: I do not like it

    Yes, addition of default value was the most obvious improvement for my implementation (I thought that those who are really interested in my idea will implement this as an exercise even without being asked to do so).

    Return type deduction is really great in this case, thank you for this idea. But you still can't replace a member function with an ordinary function, since C++ won't allow you to call it as create_vec<int>(n, m).

    • »
      »
      »
      8 years ago, # ^ |
        Vote: I like it 0 Vote: I do not like it

      "... since C++ won't allow you to call it as create_vec<int>(n, m)"

      I think it will.