I have a container class that operates on pixels in various formats. Some formats just store the pixels in memory, so the reference type of the container is Pixel&. Other formats store the pixels in packed bytes. There's nothing to return a reference to, so the reference type in that case is a proxy type. All of my proxy types have an embedded typedef called value_type, which is the type of the underlying pixel.
I'm running into a problem when I try to write functors that operate on pixels. For instance, I'd like to be able to write something like:
std::for_each( container.begin(), container.end(), Incrementer() );
I've been able to get this to work two different ways, but I don't like either of them, so I'm wondering if this can be improved.
The first method is:
struct Incrementer {
template <typename Pixel>
void operator()( Pixel& p ) {
p = p + 1;
}
template <typename Proxy>
void operator()( Proxy p, typename Proxy::value_type* dummy=0 ) {
p = p + 1;
}
};
The basic idea is that I have two overloads, one for the case where the container returns references to pixels and one where it returns proxies. I need that dummy argument for the second overload so that the reference case is unambiguous. The problem with this is that every functor I use needs these two overloads (including the dummy argument), so I think the interface is rather ugly.
Perhaps I could write some template magic to sort out the argument type, but I keep running into the problem that the compiler will never infer a reference argument, so I need to provide an overload with a non-const reference. A proxy, on the other hand, is a temporary, so it cannot be passed by non-const reference. That leaves me stuck with two overloads.
Is there something I'm missing?
The fallback solution would be something like:
template < typename PixelReference >
struct Incrementer {
void operator()( PixelReference p ) {
p = p + 1;
}
};
std::for_each( container.begin(), container.end(),
Incrementer< pixel_traits<Pixel,Format>::reference >() );
(assuming I have a traits class for pixels). Now I have to specify the reference type when the functor is created, which is often cumbersome.
Is there any way I can improve on either of these alternatives? I'm writing this container as a library, so I'm trying to make writing and using functors as easy as possible.
Thanks.