standardkonforme friend template funktionen



  • Ich habe gestern ein altes Projekt rausgekramt, daß ich noch mit dem MSVC.NET (VC7.0) erzeugt hatte (und dort auch läuft).

    Jetzt bei Verwendung des MSVC.NET 2003 (VC7.1) erzeugt mir der Compiler (bzw. der Linker) jedoch einige Fehlermeldungen.

    Ich habe eine template-Klasse 'd_array' und eine Test-Funktion dazu geschrieben, welche als friend deklariert sein soll, damit sie auf interne (private) Member zugreifen kann. Sie steht extra in einer anderen Datei.

    Hier die Testfunktion(en):

    template <typename T, unsigned short N>
    void test_d_array(const d_array<T, N>& array)
    {
    	cout << "Array" << N << ":" << endl;
    	for(int i=0; i<N; i++)
    		cout << array.st_offsets[i] << endl;
    	cout << "Size: " << array.size << endl;
    
    	for(int y=0; y < N; y++)
    	{
    		for(int x=0; x < N; x++)
    			cout << (array.check(x, y)? 'O' : 'X');
    		cout << endl;
    	}
    
    	cout << endl;
    }
    
    void test_d_arrays()
    {
    	typedef d_array<int, 8> Array8;
    	Array8 array8;
    
    	test_d_array(array8);
    
    	typedef d_array<int, 7> Array7;
    	Array7 array7;
    
    	test_d_array(array7);
    }
    

    Und hier die Template-Klasse:

    template <typename T, unsigned short N>
    class d_array
    {
    public:
         // ...
    
    private:
    	friend void test_d_array(const d_array<T, N>& array); // for tests
    
        // member
        enum { size = (N%2==0)? (N+2)*N/2 : (N*N+1)/2, M = (N+1)/2 };
    
        ...
    };
    

    Der Linker erkennt nun nicht mehr die Template Funktion 'test_d_array(...)', welche in der Funktion 'test_d_arrays()' aufgerufen werden.

    Wo ist mein (Denk-) Fehler?



  • Th schrieb:

    Sie steht extra in einer anderen Datei.

    Das dürfte (imho) der Fehler sein. Du mußt der Klasse vermutlich einen Prototyp vorgeben, bevor du deine Klasse definierst. Oder du mußt dem Compiler zumindest sagen, daß er es hier mit einer Template-Funktion zu tun hat:

    template<> friend void test_d_array(const d_array<T, N>& array); // for tests
    

    (oder so ähnlich - den genauen Syntax habe ich nicht im Kopf, weil ich ihn noch nie verwendet habe)



  • Danke für den Tip.

    Nach einigem Ausprobieren hier nun die Lösung:
    (wichtig war das Einfügen von <T, N> bei der friend Deklaration !!!)

    template <typename T, unsigned short N> class d_array; // forward declaration to class
    
    template <typename T, unsigned short N>
    void test_d_array(const d_array<T, N>& array); // declaration of test function
    
    template <typename T, unsigned short N>
    class d_array
    {
    public:
         // ...
    
    private:
        friend void test_d_array<T, N>(const d_array<T, N>& array); // for tests
    
        // member
        enum { size = (N%2==0)? (N+2)*N/2 : (N*N+1)/2, M = (N+1)/2 };
    
        ...
    };
    

Anmelden zum Antworten