Alle Elemente einer Strukt ermitteln



  • Dummkopf schrieb:

    Gehen wir davon aus, dass sich in der Struktur eine weitere Struktur befindet. Wie kann man "hausfinden", ob sich nun in der Struktur eine weitere Struktur befindet?

    Gar nicht. Allenfalls kannst du rausfinden, ob noch mehr als zwei Integer drin stecken ( Alingment auf 1 setzen). Was es ist ( zwei int, eine struct, ein double ) ist unbekannt.



  • variabl0r schrieb:

    Die Füllbytes werden doch ans Ende der Struktur angehängt, bzw. die Struktur wird dadurch größer.
    Die Anordnung der Elemente in der Struktur garantiert ein bitweises Abbild im Speicher.

    Da bist du falsch informiert. Der C++-Standard sagt ausdrücklich:

    9.2/12 schrieb:

    Nonstatic data members of a (non-union) class declared without an intervening access-specifier are allocated so that later members have higher addresses within a class object. The order of allocation of nonstatic data members separated by an access-specifier is unspecified (11.1). Implementation alignment requirements might cause two adjacent members not to be allocated immediately after each other; so might requirements for space for managing virtual functions (10.3) and virtual base classes (10.1).



  • Nexus schrieb:

    Da bist du falsch informiert.

    Jepp. 😞



  • Wozu soll das überhaupt gut sein? Vielleicht ist ja sowas in der Art gefragt:

    #include <string>
    #include <iostream>
    #include <vector>
    
    using namespace std;
    
    class ElementBase
    {
    public:
    
    	string Name;
    
    	ElementBase(const char *_name)
    		: Name(_name)
    	{
    	}
    };
    
    class Container;
    
    template <class T>
    class Element : public ElementBase
    {
    public:
    
    	T Value;
    
    	Element(Container *_container, const char *_name, const T &_value);
    
    	T &operator * ();
    
    	T *operator -> ();
    };
    
    class Container
    {
    public:
    
    	template <class T>
    	void add(Element<T> *_ele)
    	{
    		Elements.push_back(_ele);
    	}
    
    	template <class T>
    	T &get(const char *_name)
    	{
    		for (size_t i = 0; i < Elements.size(); ++i)
    		{
    			if (Elements->Name == _name)
    			{
    				return ((Element<T>*)(Elements[i ]))->Value;
    			}
    		}
    
    		return ((Element<T>*)(Elements[0]))->Value;
    	}
    
    	//size_t getElementCount()
    
    	//...
    
    protected:
    
    	vector<ElementBase*> Elements;
    
    };
    
    template <class T>
    Element<T>::Element(Container *_container, const char *_name, const T &_value)
    	: ElementBase(_name)
    	, Value(_value)
    {
    	_container->add(this);
    }
    
    template <class T>
    T &Element<T>::operator * ()
    {
    	return Value;
    }
    
    template <class T>
    T *Element<T>::operator -> ()
    {
    	return &Value;
    }
    
    #define CONT_ELEMENT(name, val) name(this, #name, val)
    
    class Test : public Container
    {
    public:
    
    	Element<int> Number;
    
    	Test()
    		: CONT_ELEMENT(Number, 0)
    	{
    	}
    };
    
    int main()
    {
    	Test t;
    
    	t.get<int>("Number") = 1234;
    
    	cout << t.get<int>("Number") << endl;
    
    	cin.get();
        return 0;
    }
    

    Die Frage war ja [i]"Wie ist es den möglich auf die einzelnen Variablen der Struktur zuzugreifen ohne die Namen der Variablen zu wissen?"*, und Container lässt sich einfach derartig erweitern.

    Bitte keine Kommentare, dass dieser Code unnütz oder ineffizient ist! Er soll nur zeigen, wie man zur Laufzeit die Elemente einer Struktur ermitteln könnte, wenn sie entsprechend angelegt worden ist.



  • mein vorschlag:

    struct Test
    {
        enum {number,foo,bar,SIZE};
        int data[SIZE];
        int& get(int index)
        {
            return data[index];
        }
    };
    int main()
    {
        Test t;
        t.get(Test::number) = 1234;
        cout << t.get(Test::number) << '\n';
        cin.get();
        return 0;
    }
    

    man kann damit auch

    for(int i=0;i<Test::SIZE;++i)
       cout<<t.get(i)<<'\n';
    

    machen oder sogar den typ Test als template-typ-parameter.



  • 1. wieso eigtl enum {number,foo,bar,SIZE}; ? brauchst ja iwie nur SIZE...

    und außerdem:

    2. wieso sieht man konstanten so oft als enums anstatt const size_t oder was auch immer der richtige typ wäre?! nur schreibfaulheit oder gibts da noch irgendwo vorteile?

    bb



  • unskilled schrieb:

    2. wieso sieht man konstanten so oft als enums anstatt const size_t oder was auch immer der richtige typ wäre?! nur schreibfaulheit oder gibts da noch irgendwo vorteile?

    Das sieht einfach mehr nach Konstante aus, schneller als solche erkennbar, und natürlich kürzer. Warum soll man auch den langen Typ hinschreiben, wenn der Compiler bei einem Enum automatisch int oder unsigned int nimmt.



  • unskilled schrieb:

    1. wieso eigtl enum {number,foo,bar,SIZE}; ? brauchst ja iwie nur SIZE...

    Ich will nicht nur mit Schleife durchlaufen, sondern alternativ auch benannte Members haben.

    t.get(Test::durchschnitt)=t.get(Test::summe)/t.get(Test::anzahl);
    

    2. wieso sieht man konstanten so oft als enums anstatt const size_t oder was auch immer der richtige typ wäre?! nur schreibfaulheit oder gibts da noch irgendwo vorteile?

    in diesem fall will ich fortlaufende zahlen von 0 bis SIZE haben. das macht enum so toll automatisch. anderenfalls hätte ich natürlich eine normale konstante genommen.



  • Was? Variablen in einer Struktur sind nicht zwingend hintereinander im Speicher angeordnet?
    What the heck? Darauf verlassen sich aber viele... Und ich hatte seit Jahren noch nie Probleme...

    😕 ⚠



  • ok - leuchtet mir ein ^^

    Cast0r schrieb:

    Was? Variablen in einer Struktur sind nicht zwingend hintereinander im Speicher angeordnet?
    What the heck? Darauf verlassen sich aber viele... Und ich hatte seit Jahren noch nie Probleme...

    😕 ⚠

    iwie hast du hier was falsch verstanden ^^



  • Cast0r schrieb:

    Was? Variablen in einer Struktur sind nicht zwingend hintereinander im Speicher angeordnet?

    Insofern hintereinander, dass Variablen, die später deklariert sind, höhere Adressen haben (innerhalb des gleichen Zugriffsspezifizierers). Aber nicht, dass sie direkt aufeinanderfolgen müssen, also die Grösse einer Struktur der Summe aller Membergrössen entsprechen muss.

    Cast0r schrieb:

    What the heck? Darauf verlassen sich aber viele... Und ich hatte seit Jahren noch nie Probleme...

    Das heisst ja nichts. Wenn du mit einer bestimmten Implementierung arbeitest und weisst, wie sich diese verhält, oder sogar das Alignment beeinflussen kannst, geht das lange gut. Der Standard garantiert es trotzdem nicht, was ich aber nicht für so schlimm halte. In C++ werkelt man nicht so häufig mit rohen Structs und Zeigern rum wie zum Beispiel in C. Oft handelt es sich nicht mal um PODs, und in solchen Fällen ist byteweises Rumhantieren sowieso verboten. Deshalb ist es meistens keine Einschränkung, dass man sich nicht auf die interne Anordnung und Ausrichtung der Member verlassen kann.



  • Dummkopf schrieb:

    Wie ist es den möglich auf die einzelnen Variablen der Struktur zuzugreifen ohne die Namen der Variablen zu wissen? 😕

    Beschreibe am besten präzise Dein übergeordnetes Ziel statt so eine spezielle Frage zu stellen, ohne weitere Details zu nennen. Siehe Punkt 7 von "Du brauchst Hilfe?".

    C++ ist relativ "Ballast-frei", was Metadaten angeht. Reflexion gibt es weder zur Laufzeit (würde Metadaten erfordern) noch zur Compile-Zeit.

    Die beste Antwort auf Deine Frage ist meiner Meinung nach immer noch: "Geht nicht! Was willst Du eigentlich?" -- auch wenn es mit dem "Geht nicht" nicht die ganze Wahrheit ist. :p

    Gruß,
    SP



  • Sieht aus wie ein Troll: Ich will, ich will, ich will ...
    C++ hat kein Reflection von Haus aus. Es existieren keine Namen fuer Attribute nach dem Kompilieren. Es geht nicht. Alle geposteten Versuche halte ich fuer schlecht, da sie die Abstraktion (struct) durchbrechen und auf der jeweiligen Implementation (roher Speicher) operieren.



  • Ich gehe auch mal stark davon aus, dass es eine deutlich bessere Lösung für sein Problem gibt.

    Vielleicht könnte er mal seine Zielsetzung ausplaudern. So geheim und innovativ wird es schon nicht sein, als das jemand sein Wissen klauen könnte 🙂


Anmelden zum Antworten