画像クラスを次のように表すとします。
template <typename Pixel> class Image { ... };
画像の余分なコピーを防ぐために独自の swap 関数が必要になるため、Image のフレンドにする必要があります。画像内の場合、次のように記述します。
template <typename T> friend void swap(Image<T>&, Image<T>&);
私は欲しいものを手に入れましたが、それはすべてのスワップ関数をすべての Image クラスの友達にします。したがって、次のように友人関係を絞り込むことができます。
template <typename Pixel> class Image;
template <typename T> void swap(Image<T>&, Image<T>&);
template <typename Pixel> class Image {
...
friend void swap<>(Image&, Image&);
};
C++ FAQ-lite 35.16で説明されているように。
ここで、浮動小数点または整数カーネルを使用できる畳み込み関数もあるとします。
template <typename Pixel, typename KernelValue>
Image<Pixel> convolve(const Image<Pixel>&, const Kernel<KernelValue>&);
Convolution は Image の raw メモリにアクセスする必要があるため、これも友人でなければなりません。ただし、convolve がすべての KernelValues のフレンドであるが、特定の Pixel タイプのみのフレンドになるように、フレンドシップを部分的に狭めたいと思います。
template <typename KernelValue> friend Image<Pixel>
convolve(const Image<Pixel>&, const Kernel<KernelValue>&);
イメージ定義内。コンパイラは、これ (または他のバリアント) をまったく好まない。主な理由は、元の関数宣言と一致しないため、プライベート ポインターにアクセスできないためです。ここで私が欲しいものを手に入れることは可能ですか、それとも「より使いやすい」バージョンで解決する必要がありますか?