我有一个对各种格式的像素进行操作的容器类。有些格式只是将像素存储在内存中,所以容器的引用类型是 Pixel&。其他格式将像素存储在打包字节中。没有什么可以返回引用,所以这种情况下的引用类型是代理类型。我所有的代理类型都有一个名为 value_type 的嵌入式 typedef,它是底层像素的类型。
当我尝试编写对像素进行操作的函子时,我遇到了问题。例如,我希望能够编写如下内容:
std::for_each( container.begin(), container.end(), Incrementer() );
我已经能够让它以两种不同的方式工作,但我不喜欢其中任何一种,所以我想知道这是否可以改进。
第一种方法是:
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;
}
};
基本思想是我有两个重载,一个用于容器返回对像素的引用的情况,一个用于返回代理的情况。我需要第二个重载的虚拟参数,以便参考案例是明确的。问题是我使用的每个仿函数都需要这两个重载(包括虚拟参数),所以我认为接口相当丑陋。
也许我可以编写一些模板魔术来整理参数类型,但我一直遇到编译器永远不会推断引用参数的问题,所以我需要提供一个带有非常量引用的重载。另一方面,代理是临时的,因此不能通过非常量引用传递。这让我陷入了两个重载。
有什么我想念的吗?
后备解决方案类似于:
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 >() );
(假设我有一个像素特征类)。现在我必须在创建仿函数时指定引用类型,这通常很麻烦。
有什么办法可以改进这些替代方案中的任何一个吗?我把这个容器写成一个库,所以我试图让编写和使用函子尽可能容易。
谢谢。