Reputation: 761
I have a bunch of structs like:
struct A { ... }
struct B { ... }
struct C { ... }
I want to devise a function that can accept arrays of these structs and iterate through each element of the array and call another function like:
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];
// in practice, this is actually operator<<, so I cannot pass in the
// size explicitly
process(..., a_array);
Update: I cannot use any of the std containers here. It has to be an array unfortunately!
Upvotes: 1
Views: 3110
Reputation: 146910
Array-to-pointer decay is really, really bad.
Fortunately, C++ has array references, which know their size.
template<typename T, size_t N> ostream& process(ostream& os, const T (&arr)[N]) {
// use N
}
Upvotes: 10
Reputation: 3322
You need to use the following format for arrays:
template <typename T, size_t N>
void foo(const T (&arr)[N]) {
...
}
Otherwise, size information will be lost.
Upvotes: 2
Reputation: 114
Or, a simple template bounds checked array.
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 ];
};
And then
template< typename T, unsigned int Size >
void Process( Array< T, Size >& array )
{
for( unsigned int i = 0; i < Size; ++i )
{
//use array[i]
}
}
And to tie it together
Array< int, 10 > array;
Process( array );
It's a bit of a roll your own solution, but it's probably roughly equivalent (although a less functional array class) to std::Array or boost
Upvotes: 0
Reputation: 13560
You could use a std::vector<T>
instead of an simple array.
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)
{
//...
}
}
Or you can go the std::array way (If your compiler support it and N is constant).
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);
Upvotes: 7