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

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

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.