2009-05-06 4 views
2

Angenommen, ich vertrete eine Bildklasse:Ist es möglich, die Freundesbeziehung zwischen Klassen und Funktionen einzuschränken, wenn mehrere Schablonentypen beteiligt sind?

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

würde ich meine eigene Swap-Funktion benötigt zusätzliche Kopieren von Bildern zu verhindern, so würde ich brauche es einen Freund von Bild zu machen. Wenn innerhalb Bild Ich schreibe:

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

ich bekommen, was ich will, aber es macht alle Swap-Funktionen Freunde aller Bildklassen. So kann ich den Freund Beziehung verengen wie folgt:

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

template <typename Pixel> class Image { 
    ... 
    friend void swap<>(Image&, Image&); 
}; 

wie in C++ FAQ-lite 35.16 beschrieben.

Jetzt nehme ich auch eine Faltungsfunktion haben, die Floating-Point oder Integralkerne nehmen:

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

Convolution benötigt Zugriff auf Bild des rohen Speicher, so ist auch er ein Freund sein muss. Ich möchte jedoch auf teilweise schmal die Freundschaft so dass convolve einen Freund für alle KernelValues ​​ist aber nur die bestimmte Pixel Art, so etwas wie:

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

innerhalb der Bildschärfe. Der Compiler mag dies (oder andere Varianten) überhaupt nicht, hauptsächlich weil er nicht mit der ursprünglichen Funktionsdeklaration übereinstimmt, so dass auf den privaten Zeiger nicht zugegriffen werden kann. Ist es möglich, hier zu bekommen, was ich will, oder sollte ich mich mit der "freundlicheren" Version zufrieden geben?

Antwort

1

Der einzige Weg, ich geschieht dies sehen die Funktion innerhalb der Image-Klasse ist die Definition, etwa so:

#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); 
} 
3

Soweit ich weiß, können Sie keine teilweise spezialisierte Vorlagenfunktion haben.

Sie könnten eine Convolver Struktur erstellen, die Sie teilweise spezialisieren können und dann einen Wrapper erstellen, um die Convolve zu tun.

Verwandte Themen