2

假设我将一个图像类表示为:

template <typename Pixel> class Image { ... };

我需要自己的交换功能来防止额外复制图像,所以我需要让它成为 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>&);

卷积需要访问 Image 的原始内存,所以它也必须是一个朋友。但是,我想部分缩小友谊,以便 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 回答