Avoiding copying of an object

A

Adam Markiewicz

I'm designing a container class similar to those in STL. It is implemented
as a template with two parameters: contained type and an allocator.

template <typename Type, typename Allocator>
class FixedArray
{
...
}

Now, to write a function that takes FixedArray as a param to support
different allocators I would need (example):

template <typename Allocator>
float average(const FixedArray<float, Allocator>& array);

However array is const, so Allocator wouldn't be needed at all. Is would be
much simpler to write:

float average(const FixedArray<float>& array);

This syntax can be provided by specifying a suitable copy constructor, but
I want to avoid unnecessary copying overhead. Is there some other
clean solution to this problem?
 
J

Juha Nieminen

Adam Markiewicz said:
I'm designing a container class similar to those in STL. It is implemented
as a template with two parameters: contained type and an allocator.

template <typename Type, typename Allocator>
class FixedArray

Actually if you want it to be like the standard library containers, you
would have to make the allocator have a default value (so that the class
can be used without having to specify one explicitly), in other words:

Now, to write a function that takes FixedArray as a param to support
different allocators I would need (example):

template <typename Allocator>
float average(const FixedArray<float, Allocator>& array);

However array is const, so Allocator wouldn't be needed at all. Is would be
much simpler to write:

float average(const FixedArray<float>& array);

If you want your function to support different types of 'FixedArray'
which use different allocators, the only way to do that is to make it
a template function where the allocator type is templatized, as you did
in the first example. That's because template classes with differing
template types are, effectually, completely different and independent
class types. It's like you had given them completely different names.
 
M

Marc

Adam said:
I'm designing a container class similar to those in STL. It is implemented
as a template with two parameters: contained type and an allocator.

template <typename Type, typename Allocator>
class FixedArray
{
...
}

Now, to write a function that takes FixedArray as a param to support
different allocators I would need (example):

template <typename Allocator>
float average(const FixedArray<float, Allocator>& array);

However array is const, so Allocator wouldn't be needed at all. Is would be
much simpler to write:

float average(const FixedArray<float>& array);

I assume making average a member function is not an option.
This syntax can be provided by specifying a suitable copy constructor, but
I want to avoid unnecessary copying overhead. Is there some other
clean solution to this problem?

I think it is best to stick to the version with a template, as
disappointing as it may be. If you insist, might something like this
work?

template <typename Type>
class ConstFixedArray
{
...
}
template <typename Type, typename Allocator>
class FixedArray : public ConstFixedArray<Type>
{
...
}
float average(const ConstFixedArray<float>& array);

If FixedArray<T> (default allocator) is only used in read-only contexts,
you can try to optimize your version with a copy constructor to not do
the copying, but you probably need C++0X to properly detect the cases
where the vector is a temporary and needs help staying alive.
 
S

SG

I'm designing a container class similar to those in STL. It is implemented
as a template with two parameters: contained type and an allocator.

template <typename Type, typename Allocator>
class FixedArray
{
    ...
}

Now, to write a function that takes FixedArray as a param to support
different allocators I would need (example):

template <typename Allocator>
float average(const FixedArray<float, Allocator>& array);

However array is const, so Allocator wouldn't be needed at all. Is would be
much simpler to write:

float average(const FixedArray<float>& array);

This syntax can be provided by specifying a suitable copy constructor, but
I want to avoid unnecessary copying overhead. Is there some other
clean solution to this problem?

Making 'average' a function template might not be a bad idea. What if
you also need it for T=double, T=complex<float>, etc? The STL-way of
writing such a function would be to make it a template that accepts a
pair of iterators. See std::accumulate.

Another solution would be to use inheritance:

template<class T>
class fixed_array_base
{
public:
std::size_t size() const {return end_ - begin_;}
T & operator[](std::size_t idx)
{ assert(idx<size()); return begin_[idx]; }
T const& operator[](std::size_t idx) const
{ assert(idx<size()); return begin_[idx]; }
protected:
fixed_array_base() : begin_(0), end_(0) {}
~fixed_array_base() {}
T* begin_;
T* end_;
private:
fixed_array_base(fixed_array_base const&);
fixed_array_base& operator=(fixed_array_base const&);
};

template<class T, class Alloc = std::allocator<T> >
class fixed_array : public fixed_array_base<T>
{
public:
explicit fixed_array(std::size_t n, Alloc const& a = Alloc());
fixed_array(fixed_array const&);
fixed_array& operator=(fixed_array const&);
~fixed_array();
private:
Alloc allocator_;
};

which could be used like this:

float average(fixed_array_base<float> const& fa);

float test() {
fixed_array<float,custom_alloc> numbers (100);
for (int k=0; k<100; ++k)
numbers[k] = k;
return averate(numbers);
}

HTH,
SG
 
C

Carfield Yim

This syntax can be provided by specifying a suitable copy constructor, but
I want to avoid unnecessary copying overhead. Is there some other
clean solution to this problem?

In fact how often we get performance problem by copying overhead??
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,994
Messages
2,570,223
Members
46,813
Latest member
lawrwtwinkle111

Latest Threads

Top