さまざまな形式のピクセルを操作するコンテナー クラスがあります。一部の形式はピクセルをメモリに格納するだけなので、コンテナーの参照型は Pixel& です。他の形式では、ピクセルがパックされたバイトで格納されます。参照を返すものがないため、その場合の参照型はプロキシ型です。すべてのプロキシ タイプには、基になるピクセルのタイプである value_type という組み込みの typedef があります。
ピクセルを操作するファンクターを作成しようとすると、問題が発生します。たとえば、次のようなものを書きたいと思います。
std::for_each( container.begin(), container.end(), Incrementer() );
これを2つの異なる方法で機能させることができましたが、どちらも好きではないので、これを改善できるかどうか疑問に思っています.
最初の方法は次のとおりです。
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;
}
};
基本的な考え方は、コンテナーがピクセルへの参照を返す場合とプロキシを返す場合の 2 つのオーバーロードがあるということです。参照ケースが明確になるように、2 番目のオーバーロードの仮引数が必要です。これの問題は、私が使用するすべてのファンクターがこれら 2 つのオーバーロード (仮引数を含む) を必要とすることです。
おそらく、引数の型を整理するためのテンプレート マジックを作成することもできますが、コンパイラが参照引数を推論しないという問題に直面し続けるため、非 const 参照を使用してオーバーロードを提供する必要があります。一方、プロキシは一時的なものであるため、非 const 参照で渡すことはできません。そのため、2 つのオーバーロードで立ち往生しています。
足りないものはありますか?
フォールバック ソリューションは次のようになります。
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 >() );
(ピクセルの特性クラスがあると仮定します)。ここで、ファンクタを作成するときに参照型を指定する必要がありますが、これは面倒なことがよくあります。
これらの代替案のいずれかを改善する方法はありますか? 私はこのコンテナーをライブラリーとして作成しているので、ファンクターの作成と使用をできるだけ簡単にしようとしています。
ありがとう。