Templates Friend



  • Hallo,

    ich mal einen kompilierfähigen Beispielcode zusammengestellt, der mein Problem ganz gut darlegt:

    #include <iostream>
    #include <exception>
    
    using namespace std;
    
    template<typename _Ty, size_t _n>
    class BoundArray
    {
    private:
    	size_t _last_idx;
    	_Ty _arr[_n];
    
    public:
    	_Ty operator[] (size_t idx)
    	{
    		this->_last_idx = idx;
    		if( idx < _n )
    			return this->_arr[idx];
    		else
    			throw out_of_range("idx is out of range");
    	}
    
    	template<typename __Ty, size_t __n>
    	friend _Ty GetFromArray(BoundArray<__Ty, __n>&, size_t);
    };
    
    template<typename _Ty, size_t _n>
    _Ty GetFromArray(BoundArray<_Ty, _n>& arr, size_t idx)
    {
    	_Ty ret_val;
    	try
    	{
    		ret_val = arr[idx];
    	}
    	catch(out_of_range e)
    	{
    		memset(&ret_val, 0, sizeof(_Ty));
    		cout << e.what() << endl;
    		cout << arr._last_idx << endl;
    	}
    
    	return ret_val;
    }
    
    int main()
    {
    	BoundArray<int, 20> arr;
    
    	for( int i = 0; i < 30; i++ )
    		cout << GetFromArray(arr, i) << endl;
    
    	return 0;
    }
    

    Die Funktion GetFromArray() soll auf die private Member von BoundArray zugreifen können. Ich kam jedoch nicht umher extra template<typename, size_t> vor die friend deklaration schreiben zu müssen.
    Warum kann ich nicht einfach

    friend _Ty GetFromArray(BoundArray<_Ty, _n>&, size_t);
    

    verwenden?

    Es ist doch korrekt, dass speziell zu dieser speziellen Klasse GetFromArray() eine Friend Routine sein soll.

    Ich bekomm dann aber nicht aufgelöste Verweise:

    error LNK2019: unresolved external symbol "int __cdecl GetFromArray(class BoundArray<int,20> &,unsigned int)" (?GetFromArray@@YAHAAV?$BoundArray@H$0BE@@@I@Z) referenced in function _main	main.obj
    

  • Mod

    FrEEzE2046 schrieb:

    Warum kann ich nicht einfach

    friend _Ty GetFromArray(BoundArray<_Ty, _n>&, size_t);
    

    verwenden?

    Kasnnst du, das deklariert allerdings eine normale nicht-Template-Funktion als friend.
    Du kannst eine Spezialisierung als friend deklarieren, dann muss aber nat. das Primärtemplate zuvor schon deklariert worden sein.

    FrEEzE2046 schrieb:

    Ich bekomm dann aber nicht aufgelöste Verweise:

    error LNK2019: unresolved external symbol "int __cdecl GetFromArray(class BoundArray<int,20> &,unsigned int)" (?GetFromArray@@YAHAAV?$BoundArray@H$0BE@@@I@Z) referenced in function _main	main.obj
    

    Das ist Folge eines einfachen Tippfehlers, der weitaus auffälliger wäre, wenn du nicht diese furchtbaren reservierten Bezeichner verwenden würdest (Unterstriche zählen).



  • C++, where friends can touch your privates.



  • Stolperfalle:
    Du benutzt memset in einer template Klasse/Funktion, ohne sicherzustellen, dass der Template Parameter tatsächlich ein POD ist. Kann schon mal in die Hose gehen...



  • camper schrieb:

    Das ist Folge eines einfachen Tippfehlers, der weitaus auffälliger wäre, wenn du nicht diese furchtbaren reservierten Bezeichner verwenden würdest

    Die STL des MS-Compilers ist kein gutes Stil-Vorbild. 🙂

    camper schrieb:

    (Unterstriche zählen).

    Zählen reicht nicht:

    Each name that contains a double underscore (_ _) or begins with an underscore followed by an uppercase letter (2.11) is reserved to the implementation for any use


Anmelden zum Antworten