代码之家  ›  专栏  ›  技术社区  ›  Mark Ruzon

当涉及多个模板类型时,是否可以缩小类和函数之间的友元关系?

  •  2
  • Mark Ruzon  · 技术社区  · 16 年前

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

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

    我需要自己的交换功能来防止额外复制图像,所以我需要让它成为图像的朋友。如果我在图像里写:

    template <typename T> friend void swap(Image<T>&, Image<T>&);
    

    我得到了我想要的,但它使所有交换函数成为所有图像类的朋友。所以我可以把朋友关系缩小如下:

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

    卷积需要访问图像的原始内存,因此它也必须是朋友。不过,我想 部分狭窄 这种友谊使卷积成为所有内核值的朋友,但只有特定的像素类型,比如:

    template <typename KernelValue> friend Image<Pixel> 
        convolve(const Image<Pixel>&, const Kernel<KernelValue>&);
    

    在图像定义中。编译器根本不喜欢这个(或其他变体),主要是因为它与原始函数声明不匹配,所以无法访问私有指针。有没有可能在这里得到我想要的,或者我应该接受“更友好”的版本?

    2 回复  |  直到 16 年前
        1
  •  1
  •   Yuyo    16 年前

    我看到这种情况的唯一方法是在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);
    }
    
        2
  •  3
  •   user21714    16 年前

    据我所知,您不能具有部分专用的模板化函数。

    你可以做一个 卷积器 结构,您可以部分专用化,然后创建一个包装器来进行卷积。