Короткий вопрос: Есть ли более короткий способ сделать это?
array<array<atomic<int>,n>,m> matrix;
Я надеялся на что-то вроде
array< atomic< int>,n,m> matrix;
но он не работает...
Короткий вопрос: Есть ли более короткий способ сделать это?
array<array<atomic<int>,n>,m> matrix;
Я надеялся на что-то вроде
array< atomic< int>,n,m> matrix;
но он не работает...
При вставке std:: array может стать очень трудным для чтения и излишне подробным. Противоположный порядок размеров может быть особенно запутанным.
Например:
std::array < std::array <int, 3 > , 5 > arr1;
по сравнению с
char c_arr [5][3];
Также обратите внимание, что begin(), end() и size() возвращают бессмысленные значения, когда вы вставляете std:: array.
По этим причинам я создал свои собственные контейнеры массива с фиксированным размером, array_2d и array_3d. У них есть то преимущество, что они работают с С++ 98.
Они аналогичны std:: array, но для многомерных массивов из 2 и 3 измерений. Они более безопасны и имеют худшую производительность, чем встроенные многомерные массивы. Я не включил контейнер для многомерных массивов с размерами больше 3, поскольку они являются необычными. В С++ 11 может быть выполнена версия вариационного шаблона, которая поддерживает произвольное количество измерений (что-то вроде примера Michael Price).
Пример двумерного варианта:
//Create an array 3 x 5 (Notice the extra pair of braces)
fsma::array_2d <double, 3, 5> my2darr = {{
{ 32.19, 47.29, 31.99, 19.11, 11.19},
{ 11.29, 22.49, 33.47, 17.29, 5.01 },
{ 41.97, 22.09, 9.76, 22.55, 6.22 }
}};
Полная документация доступна здесь: http://fsma.googlecode.com/files/fsma.html
Вы можете скачать библиотеку здесь: http://fsma.googlecode.com/files/fsma.zip
Приятным обходным решением для компиляторов, которые не поддерживают псевдонимы шаблонов, все же является использование простого метафайла для генерации типа:
#include <cstddef>
#include <array>
template<class T, std::size_t RowsN, std::size_t ColumnsN>
struct Matrix
{
typedef std::array<std::array<T, ColumnsN>, RowsN> type; // row major
private:
Matrix(); // prevent accidental construction of the metafunction itself
};
int main()
{
Matrix<int, 3, 4>::type matrix;
}
Псевдоним шаблона может помочь:
#include <array>
template <class T, unsigned I, unsigned J>
using Matrix = std::array<std::array<T, J>, I>;
int main()
{
Matrix<int, 3, 4> matrix;
}
Решение с использованием вариативных шаблонов (немного сложнее, чем псевдоним шаблона, но более общего назначения)
template <typename T, std::size_t thisSize, std::size_t ... otherSizes>
class multi_array : private std::array<multi_array<T, otherSizes...>, thisSize>
{
using base_array = std::array<multi_array<T, otherSizes...>, thisSize>;
public:
using base_array::operator[];
// TODO: add more using statements to make methods
// visible. This is less typing (and less error-prone)
// than forwarding to the base_array type.
};
template <typename T, std::size_t thisSize>
class multi_array<T, thisSize> : private std::array<T, thisSize>
{
using base_array = std::array<T, thisSize>;
public:
using base_array::operator[];
// TODO: add more using statements to make methods
// visible. This is less typing (and less error-prone)
// than forwarding to the base_array type.
};
Могут быть некоторые улучшения при назначении не-листьям массива, которые могут быть сделаны.
Я тестировал относительно недавнюю сборку clang/LLVM.
Наслаждайтесь!
Здесь простая, общая версия:
template <typename T, size_t d1, size_t d2, size_t... ds>
struct GetMultiDimArray
{
using type = std::array<typename GetMultiDimArray<T, d2, ds...>::type, d1>;
};
template <typename T, size_t d1, size_t d2>
struct GetMultiDimArray<T, d1, d2>
{
using type = std::array<std::array<T, d2>, d1>;
};
template <typename T, size_t d1, size_t d2, size_t... ds>
using MultiDimArray = typename GetMultiDimArray<T, d1, d2, ds...>::type;
// Usage:
MultiDimArray<int, 3, 2> arr {1, 2, 3, 4, 5, 6};
assert(arr[1][1] == 4);