Friend-Templates und Member
-
Hallo,
ich versuche innerhalb einer (eig. zwei) Template-Funktion auf Member zuzugreifen. Das Ganze sieht ungefähr so aus:
//Profile.hpp class Database; class Profile { template <typename T> friend bool Database::loadSingleDataset (T& outputData, std::string fieldName, keyType regKey); //Fehler #2 template <> friend bool Database::loadSingleDataset (std::string& outputData, std::string fieldName, keyType regKey); //Fehler #3 und #4 friend bool Database::loadSingleProfile (Profile& tempProfile, keyType& regKey); private: std::string profileName; //... public: //... };//Database.hpp #include "Profile.hpp" //... class Database { private: template <typename T> bool loadSingleDataset (T& outputData, std::string fieldName, keyType regKey) { //... } template <> //a template specialization bool loadSingleDataset (std::string& outputData, std::string fieldName, keyType regKey) { //... } //... };Hier will ich die Member an die Template-Funktion übergeben und dort ändern, was nicht geht:
//Database.cpp bool Database::loadSingleProfile (Profile& tempProfile, keyType& regKey) { loadResult *= loadSingleDataset<std::string>(tempProfile.profileName, "profileName", regKey); //hier kommt Fehler #1 //... }Ich erhalte gleich einen Haufen Fehlermeldungen, die auf dem 15. Blick immernoch keinen Sinn ergeben:
database.cpp(78): error C2248: "Profile::profileName": Kein Zugriff auf private Member, dessen Deklaration in der Profile-Klasse erfolgte.
profile.hpp(19): error C2039: 'loadSingleDataset': Ist kein Element von 'Database'
profile.hpp(21): error C2770: Ungültige explizite template-Argumente für "bool loadSingleDataset(T &,std::string,keyType)".
profile.hpp(21): error C2027: Verwendung des undefinierten Typs "Database"Zur 1. FM: Die Spezialisierung ist doch auch ein Kumpel... Warum passt das dem Compiler nicht?
Zur 2. FM: Nun das ist wirklich Käse.
Zur 3. FM: Die Funktionssignaturen sind identisch.
Zur 4. FM: Habe Database vorwärts deklariert.Ich vermute, dass das Ganze auf die friend-Deklaration zurückzuführen ist, bin aber im Moment "ursachenblind" und kann die Fehler nicht nachvollziehen.
Danke für eure Hilfe.
-
Du musst die Klasse zum Kumpel machen und nicht die Member-Funktionen.Äh, sry das war mist.
-
ScottZhang schrieb:
Du musst die Klasse zum Kumpel machen und nicht die Member-Funktionen.Äh, sry das war mist.
Gibt's auch 'ne kleine Erklärung dazu? Das ist so ziemlich das, was ich vermeiden will. Ich will die Daten so viel wie möglich kapseln und solche offene Schnittstellen möglichst klein machen.
Nevermind dann.
-
Nee das war gerad nen Denkfehler von mir, natürlich kannst du auch nur die Memberfkt zum Kumpel machen.
Allerdings: warum gibst du die Spezialisierung nochmal als friend an?
Mit
template <typename T> friend bool Database::loadSingleDataset (T& outputData, std::string fieldName, keyType regKey);ist doch alles gesagt.
-
Der Compiler weiß an der Stelle nur, dass es die Klasse Database gibt (dank der forward-deklaration), nicht aber welche Methoden sie hat. Jede Behauptung deinerseits bezüglich noch kommender Methodendeklarationen quittiert er deshalb mit einem Fehler. Die friend-Deklaration ist eine solche Behauptung.
Mein Tip: friend ist die stärkste Kupplung, die es in C++ überhaupt geben kann, in 90% der Fälle handelt es sich um fehlerhaftes oder zumindest fragliches Design. Überdenk nochmal dein Klassendesign

-
Danke
Ich erklär ganz kurz, was ich machen will. Im Prinzip soll in der Database-Klasse Profile (Datensätze) aud der DB geladen werden. Damit die Funktion, die die Daten für die Initialisierung eines Profils einliest und zum Verarbeitgen weitergibt, keine 10 pass-by-ref-Argumente bekommt, wollte ich gleich das zu erstellende Objekt übergeben. Ich fand die Verwendung von Kumpels hier nicht so dramatisch, weil zum Einen die friend-Funktion sowieso nichts anderes macht wie die Daten für das Profil-Objekt einlesen und zum Anderen "Profil" keine weiteren Member besitzt außer die, die aus der DB heraus initialisiert werden müssen.
Was ich machen könnte, wäre den Profil-Ctor gleich in derloadSingleDataset ()aufrufen und einen Zeiger zurückgeben. Mal schauen. Danke schon mal.Edit: Der Implikationen von friend bin ich mir bewusst. Wie ich schon sagte, ich wollte schon friends vermeiden, mir ist aber bis vorhin keine bessere Lösung eingefallen.