C ++ шаблон для массивов и зная их размер - PullRequest
1 голос
/ 04 января 2012

У меня есть куча структур вроде:

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);

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

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

Ответы [ 4 ]

10 голосов
/ 04 января 2012

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

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

template<typename T, size_t N> ostream& process(ostream& os, const T (&arr)[N]) {
    // use N
}
7 голосов
/ 04 января 2012

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

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)
   {
      //...
   }
}

Или вы можете пойти по пути 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);
2 голосов
/ 06 января 2012

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

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

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

0 голосов
/ 04 января 2012

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...