Alle Elemente einer Strukt ermitteln



  • Wie der Titel schon sagt: Wie kann man von einer Strukur alle Elemente auslesen?



  • Gar nicht, ohne den Aufbau zu kennen.

    Wozu bräuchtest du das, würden es nicht auch Container tun?



  • Nein, ich möchte das mit einer Struktur machen! Die Strukur, die ich auslesen möchte, besteht nur aus einfachen int-Werten.

    Wäre es möglich, dass man auf einen Wert in der Struktur zugreift und den Namen der Variable zu wissen? Mein Vorhaben ist es mit offsetof und sizeof die einzelnen Elemente auslesen. Nur man braucht dazu die Namen der einzelnen Elemente.



  • Dummkopf schrieb:

    Nein, ich möchte das mit einer Struktur machen! Die Strukur, die ich auslesen möchte, besteht nur aus einfachen int-Werten.

    Bestünde sie aus einem einfachen int-Array, wüßte ich einen Weg.



  • Ich möchte das aber mit eine Struktur machen, nicht einem int-Array.



  • Dummkopf schrieb:

    Ich möchte das aber mit eine Struktur machen, nicht einem int-Array.

    Du kannst natürlich versuchen, die Struktur als Array zu reinterpretieren, aber ganz ungefährlich ist das nicht.

    Wäre trotzdem nett, wenn du sagen könntest, warum es denn unbedingt eine Struktur sein muss und wofür du das brauchst. Eventuell haben wir bessere Vorschläge.



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



  • Dummkopf schrieb:

    Wäre es möglich, dass man auf einen Wert in der Struktur zugreift und den Namen der Variable zu wissen? Mein Vorhaben ist es mit offsetof und sizeof die einzelnen Elemente auslesen. Nur man braucht dazu die Namen der einzelnen Elemente.

    Du willst es machen, ohne die Namen zu kennen? Jepp, geht.
    Nen int Zeiger (int* pint) auf Strukturanfang zeigen lassen(struktur nach int* casten).
    Dann pint inkrementieren, maximal sizeof(struct xyz)/sizeof(int) -1 mal.
    Mit *pint kommst du an den Inhalt.



  • Dummkopf schrieb:

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

    Mit reinterpret_cast<int*> zum Beispiel. Allerdings müssen die int s wirklich genau aufeinanderfolgen.

    Ich würde eine statische Assertion einbauen, die prüft, ob sizeof(Struct) == AnzahlInts * sizeof(int) .



  • Nexus schrieb:

    Ich würde eine statische Assertion einbauen, die prüft, ob sizeof(Struct) == AnzahlInts * sizeof(int) .

    Das ist doch unnötig: größer darf es sein(Füllbytes), kleiner kanns nicht werden.



  • 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?

    Beispiel:

    struct Test2
    {
    	int x;
    	int y;
    };
    
    struct Test1
    {
    	int i;
    	int j;
    	Test2 k;
    };
    


  • variabl0r schrieb:

    Das ist doch unnötig: größer darf es sein(Füllbytes),

    Du widersprichst dir selbst. Oder was glaubst du, was operator++ für int* macht? Automatisch Füllbytes überspringen?

    Okay, wenn alles nur int s sind, ist Alignment sehr unwahrscheinlich, aber grundsätzlich nicht verboten.

    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?

    Kann man nach wie vor nicht. Und hier ist Alignment schon wahrscheinlicher, pass also auf.

    P.S. Das scheint ja wirklich sehr geheim zu sein, wenn du nicht einmal verraten willst, wozu du das brauchst. So wird es aber schwierig für uns, dir gute Vorschläge zu machen. Naja, du musst es ja wissen.



  • Nexus schrieb:

    Oder was glaubst du, was operator++ für int* macht? Automatisch Füllbytes überspringen?

    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.

    Nexus schrieb:

    P.S. Das scheint ja wirklich sehr geheim zu sein, wenn du nicht einmal verraten willst, wozu du das brauchst. So wird es aber schwierig für uns, dir gute Vorschläge zu machen. Naja, du musst es ja wissen.

    Jepp. Top Secret. Ich nehme an, Spielereien zur Übung.



  • 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.


Anmelden zum Antworten