2

画像クラスを次のように表すとします。

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>&);

イメージ定義内。コンパイラは、これ (または他のバリアント) をまったく好まない。主な理由は、元の関数宣言と一致しないため、プライベート ポインターにアクセスできないためです。ここで私が欲しいものを手に入れることは可能ですか、それとも「より使いやすい」バージョンで解決する必要がありますか?

4

2 に答える 2

3

私の知る限り、部分的に特殊化されたテンプレート関数を持つことはできません。

部分的に特殊化できるConvolver構造体を作成してから、畳み込みを行うラッパーを作成できます。

于 2009-05-06T17:16:20.530 に答える
1

これが発生しているのを確認する唯一の方法は、次のようにImageクラス内で関数を定義することです。

#include <iostream>
using std::cout;

template <typename Pixel>
struct image
{
    template <typename KernelValue>
    friend image<Pixel> convolve(image<Pixel> const&, image<KernelValue> const&)
    {
            cout << "foo\n";
            return image<Pixel>();
    }
};

int main()
{
    image<int> i;
    image<float> i2;

    convolve(i, i2);
}
于 2009-05-07T14:28:51.800 に答える