Шаблон С++ для массивов и знание их размера

У меня есть куча таких структур, как:

struct A { ... }
struct B { ... }
struct C { ... }

Я хочу создать функцию, которая может принимать массивы этих структур и перебирать каждый элемент массива и вызывать другую функцию:

template <typename t="">
ostream& process(ostream& os, const T* array) { // output each element of array to os (but how do we know the length?)
}
A a_array[10];
process(a_array);
</typename>

Я не могу передать размер массива явно, поскольку функция процесса фактически является оператором <<() (я просто использовал процесс для демонстрационных целей)

Обновление: я не могу использовать какой-либо из std-контейнеров здесь. К сожалению, это должен быть массив!

4 ответа

Затухание от массива к указателю действительно, очень плохое.

К счастью, C++ имеет ссылки на массивы, которые знают их размер.

template<typename t,="" size_t="" n=""> ostream& process(ostream& os, const T (&arr)[N]) { // use N
}
</typename>


Вы можете использовать std::vector вместо простого массива.

template <typename t="">
ostream& process(ostream& os, const std::vector<t> &array) { for(std::vector<t>::const_iterator iterator = array.begin(); iterator != array.end(); ++iterator) { //... }
}
</t></t></typename>

Или вы можете перейти по пути std :: array (если ваш компилятор поддерживает его, а N - постоянный).

template <typename t,="" int="" n="">
ostream& process(ostream& os, const std::array<t, n=""> &array) { for(std::array<t, n="">::const_iterator iterator = array.begin(); iterator != array.end(); ++iterator) { //... }
}
// Usage:
array<int, 10=""> test;
process(..., test);
</int,></t,></t,></typename>


Или простой шаблон с проверенным массивом.

template< typename T, unsigned int Size >
class Array
{ public: T& operator[]( unsigned int index ) { assert( index < Size ); return mElements[ index ]; } const T& operator[]( unsigned int index ) const { assert( index < Size ); return mElements[ index ]; } unsigned int Capacity() const { return Size; } private: T mElements[ Size ];
};

А потом

template< typename T, unsigned int Size >
void Process( Array< T, Size >& array )
{ for( unsigned int i = 0; i < Size; ++i ) { //use array[i] }
}

И связать это вместе

Array< int, 10 > array;
Process( array );

Это немного сводит ваше собственное решение, но оно, вероятно, примерно эквивалентно (хотя и менее функциональному классу массива) для std :: Array или boost


Для массивов необходимо использовать следующий формат:

template <typename t,="" size_t="" n="">
void foo(const T (&arr)[N]) { ...
}
</typename>

В противном случае информация о размере будет потеряна.

licensed under cc by-sa 3.0 with attribution.