Template: Funktion / Variable verbergen



  • Hallo,

    ich stehe vor einem Problem.

    Ich habe eine Template Klasse die

    a) eine Funktion verwendet, auf die kein Zugriff sein soll
    b) eine static Variable beinhaltet auf die kein externer Zugriff sein soll

    Leider kann die static Variable kein Member von der Template-Klasse sein, da sie dann nur für gleiche Template-Argumente wirklich "static" wäre.

    Ich könnte Sie natürlich in ein *.cpp File auslagern, aber Methoden meiner Template-Klasse haben Zugriff auf diese Variable. Da ich wiederum Deklaration und Definition einer Template-Methode nicht trennen kann, kann ich aus dem Header dann nciht mehr auf die Variable zugreifen.

    Die Funktion ist eigentlich nicht das Problem. Zur Not verwende ich Ihren Nutzen als Makro, was ich ja wieder per #undef "verschwinden" lassen kann.

    Aber die Variable bräuchte ich schon. Wie kann man das handeln?



  • FrEEzE2046 schrieb:

    a) eine Funktion verwendet, auf die kein Zugriff sein soll

    Äh, wie? Wieso gibt es die Funktion überhaupt? Wenn du kein Zugriff aus dem Template meinst, warum wird die Funktion dann verwendet?

    FrEEzE2046 schrieb:

    Die Funktion ist eigentlich nicht das Problem. Zur Not verwende ich Ihren Nutzen als Makro, was ich ja wieder per #undef "verschwinden" lassen kann.

    Tönt nicht sehr sauber. Wenn du uns ein wenig mehr erklärst, können wir dir vielleicht zu Alternativen raten.

    FrEEzE2046 schrieb:

    Ich könnte Sie natürlich in ein *.cpp File auslagern, aber Methoden meiner Template-Klasse haben Zugriff auf diese Variable. Da ich wiederum Deklaration und Definition einer Template-Methode nicht trennen kann, kann ich aus dem Header dann nciht mehr auf die Variable zugreifen.

    Wieso nicht? Die Deklaration kann ja trotzdem im Header stehen, für globale Variablen musst du dann eben extern nutzen.



  • Für mich klingt das irgendwie, dass du nach privaten Funktionen suchst, aber ich vermute mal, dass du die schon kennst.
    Also verrat am besten mit ein wenig (Pseudo)-Code, was du genau machen willst. (respektive eben nicht gehen soll).


  • Mod

    FrEEzE2046 schrieb:

    Leider kann die static Variable kein Member von der Template-Klasse sein, da sie dann nur für gleiche Template-Argumente wirklich "static" wäre.

    Eine Variable, die von allen möglichen Templateinstanzen geteilt wird? So evtl.

    class VariableHolder
    {
    private:
        static SomeType myVariable;
        template<typename> friend class MyTemplate;
    };
    
    template<typename T>
    class MyTemplate
    {
        // mach was mit VariableHolder::myVariable;
    };
    

    ?
    Das mit der Funktion bedarf einer Erläuterung.



  • camper schrieb:

    class VariableHolder
    {
    private:
        static SomeType myVariable;
        template<typename> friend class MyTemplate;
    };
    
    template<typename T>
    class MyTemplate
    {
        // mach was mit VariableHolder::myVariable;
    };
    

    Diesen Ansatz hatte ich zunächst auch verfolgt. Ich erhalte aber die Meldung: "Kein Zugriff auf Private-Member in der Klasse [...]".

    Wenn ich das ganze als public deklariere, dann compiliert es. Allerdings kann ich mir das friend dann auch klar sparen und die Variable direkt global deklarieren. Das macht dann auch keinen großen Unterschied mehr, wenn jeder darauf zugreifen kann.

    So wie du es gemacht hast (und ich wie gesagt auch schon versuchte), geht es bei mir jedenfalls nicht.


  • Mod

    FrEEzE2046 schrieb:

    Diesen Ansatz hatte ich zunächst auch verfolgt. Ich erhalte aber die Meldung: "Kein Zugriff auf Private-Member in der Klasse [...]".

    ...

    So wie du es gemacht hast (und ich wie gesagt auch schon versuchte), geht es bei mir jedenfalls nicht.

    Dann ist dein Compiler kaputt oder du hast doch etwas anderes gemacht. Geht nicht ist jedenfalls keine brauchbare Fehlerbeschreibung.
    Da Friendship nicht transitiv ist, wäre so zum Beispiel der direkte Zugriff in einer von MyTemplate<..> abgeleiteten Klasse nicht möglich. In diesem Falle könnte man sich aber mit einer Zugriffsfunktion in MyTemplate behelfen. Da meine Glaskugel recht trübe ist, kann ich hier nicht viel mehr sagen.



  • typedef class VariableHolder
    {
    private:
        static int myVariable;
        template<typename> friend class MyTemplate;
    } *PVariableHolder;
    
    int VariableHolder::myVariable = 0;
    
    template<typename T>
    class MyTemplate
    {
    public:
    	void test() {
    		VariableHolder::myVariable = 7;
    	}
    
    	static PVariableHolder pVarHolder;
    };
    
    template<typename T> PVariableHolder MyTemplate<T>::pVarHolder = 
    	reinterpret_cast<PVariableHolder>(&myVariable);
    
    int main()
    {
    	// VariableHolder::myVariable = 7;	 no access possible
    
    	MyTemplate<int> IntTemplate;
    	IntTemplate.pVarHolder->myVariable = 7;
    
    	return 0;
    }
    

    Diese Art von Zugriff soll möglich sein. Ich möchte einerseits in der Klasse selbst; andererseits aber auch über ein Klassenmember Zugriff auf "myVariable" haben. Für alle anderen soll Sie nicht zugänglich sein.


  • Mod

    FrEEzE2046 schrieb:

    typedef class VariableHolder
    {
    private:
        static int myVariable;
        template<typename> friend class MyTemplate;
    } *PVariableHolder;
    
    int VariableHolder::myVariable = 0;
    
    template<typename T>
    class MyTemplate
    {
    public:
    	void test() {
    		VariableHolder::myVariable = 7;
    	}
    
    	static PVariableHolder pVarHolder;
    };
    
    template<typename T> PVariableHolder MyTemplate<T>::pVarHolder = 
    	reinterpret_cast<PVariableHolder>(&myVariable);
    
    int main()
    {
    	// VariableHolder::myVariable = 7;	 no access possible
    	
    	MyTemplate<int> IntTemplate;
    	IntTemplate.pVarHolder->myVariable = 7;
    
    	return 0;
    }
    

    Das ergibt an so vielen Stellen keinen Sinn, dass ich gar nicht weiß, wo ich anfangen sollte...

    IntTemplate.pVarHolder->myVariable = 7;
    

    Wenn das jeder machen können soll (main ist auch jeder), wozu dann überhaupt die Mühe, myVariable in VariableHolder private zu machen?

    Abgesehen davon ist die Zeigerdeklaration ebenso wie dessen Initialisierung absurd.

    Kurz: ich verstehe immer noch nicht, worauf das hinauslaufen soll.



  • camper schrieb:

    Das ergibt an so vielen Stellen keinen Sinn, dass ich gar nicht weiß, wo ich anfangen sollte...

    IntTemplate.pVarHolder->myVariable = 7;
    

    Wenn das jeder machen können soll (main ist auch jeder), wozu dann überhaupt die Mühe, myVariable in VariableHolder private zu machen?

    Abgesehen davon ist die Zeigerdeklaration ebenso wie dessen Initialisierung absurd.

    Kurz: ich verstehe immer noch nicht, worauf das hinauslaufen soll.

    Ich habe auch nur versucht das "Problem" mit deinem Code darzustellen. Es soll natürlich nicht "jeder" machen können. Entschuldige meine vorherige Formulierung.

    Ich möchte, dass aus einer bestimmten Funktion (außerhalb der TemplateKlasse) und über die TemplateKlasse selbst der Zugang möglich ist.

    Die Sache mit dem Pointer müsste aber doch prinzipiell funktionieren (auch wenn es hier schwachsinnig erscheint).



  • FrEEzE2046 schrieb:

    Ich habe auch nur versucht das "Problem" mit deinem Code darzustellen.

    Du sollst nicht versuchen darzustellen, du sollst zeigen. Denn mit dem Darstellungsversuch zeigst du wiederum andere Probleme.
    Zeig doch einfach deinen Code, auf das wesentliche reduziert. Also nichts was nichts mit dem problem zu tun hat, aber alles, was man braucht, um das Problem im vollen Umfang zu erkennen.


Log in to reply