<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Methoden Zeiger für unterschiedliche Rückgabewerte]]></title><description><![CDATA[<p>Hallo!</p>
<p>Sagen wir ich habe eine Klasse mit 2 Methoden, die unterschiedliche Typen liefern:</p>
<pre><code>class Person {
...
public:
    int getAge() const;
    string getName() const;
};
</code></pre>
<p>Und jetzt will ich in einer Struktur beschreiben, was Person so kann und WIE man an die Werte kommt. Das soll so aussehen:</p>
<pre><code>Descriptor desc[] = { { &quot;age&quot;, getAge }, // Attribut age kann mit getAge() geholt werden
                      { &quot;name&quot;, getName } };
</code></pre>
<p>Wenn die getter alle den selben Rückgabetyp hätten, wäre das ja kein Problem. Aber meine getter haben unterschiedliche Rückgabetypen und somit kann ich nicht einfach einen typedef auf einen Methodenzeiger angeben.<br />
Wie könnte ich das lösen?</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/325075/methoden-zeiger-für-unterschiedliche-rückgabewerte</link><generator>RSS for Node</generator><lastBuildDate>Mon, 13 Jul 2026 09:57:49 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/325075.rss" rel="self" type="application/rss+xml"/><pubDate>Sun, 13 Apr 2014 13:10:23 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Methoden Zeiger für unterschiedliche Rückgabewerte on Sun, 13 Apr 2014 13:10:23 GMT]]></title><description><![CDATA[<p>Hallo!</p>
<p>Sagen wir ich habe eine Klasse mit 2 Methoden, die unterschiedliche Typen liefern:</p>
<pre><code>class Person {
...
public:
    int getAge() const;
    string getName() const;
};
</code></pre>
<p>Und jetzt will ich in einer Struktur beschreiben, was Person so kann und WIE man an die Werte kommt. Das soll so aussehen:</p>
<pre><code>Descriptor desc[] = { { &quot;age&quot;, getAge }, // Attribut age kann mit getAge() geholt werden
                      { &quot;name&quot;, getName } };
</code></pre>
<p>Wenn die getter alle den selben Rückgabetyp hätten, wäre das ja kein Problem. Aber meine getter haben unterschiedliche Rückgabetypen und somit kann ich nicht einfach einen typedef auf einen Methodenzeiger angeben.<br />
Wie könnte ich das lösen?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2394355</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2394355</guid><dc:creator><![CDATA[Lukan]]></dc:creator><pubDate>Sun, 13 Apr 2014 13:10:23 GMT</pubDate></item><item><title><![CDATA[Reply to Methoden Zeiger für unterschiedliche Rückgabewerte on Sun, 13 Apr 2014 13:48:58 GMT]]></title><description><![CDATA[<p>Lukan schrieb:</p>
<blockquote>
<p>Und jetzt will ich in einer Struktur beschreiben, was Person so kann und WIE man an die Werte kommt.</p>
</blockquote>
<p>Das hast du bereits fertig. Die Struktur heißt Person, da steht genau das drin was Person kann und wie man an die Werte kommt.<br />
Willst du Reflection bauen? Per String auf die Getter zugreifen? Was soll die Struktur können was Person nicht kann?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2394367</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2394367</guid><dc:creator><![CDATA[nwp3]]></dc:creator><pubDate>Sun, 13 Apr 2014 13:48:58 GMT</pubDate></item><item><title><![CDATA[Reply to Methoden Zeiger für unterschiedliche Rückgabewerte on Sun, 13 Apr 2014 13:57:49 GMT]]></title><description><![CDATA[<p>Ich fülle in meinem GUI Code große Tabellen und diese Tabellen werden beschrieben mit so Descriptor structs.</p>
<p>Um die Zellen der Tabelle zu füllen, habe ich in etwa folgenden Code:</p>
<pre><code>//---------------------------------------------------------------------------------------
QVariant PersonSet::data(const QModelIndex &amp;index, int role) const {

    if (role == Qt::DisplayRole || role == Qt::EditRole) {
        const Person&amp; person = mPersons[index.row()];
        switch(index.column()) {
            case 0:
                return person.getSymbol();
            case 1:
                return person.getDescription();
            case 2:
                 ....
</code></pre>
<p>Das werden bei mir leicht mal 30 cases. Könnte ich in diesen Descripter den getter der Person Klasse hinzufügen, könnte ich einfach sowas schreiben:</p>
<pre><code>return toString( mDescriptor[index.column()].executeGetter() );
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2394372</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2394372</guid><dc:creator><![CDATA[Lukan]]></dc:creator><pubDate>Sun, 13 Apr 2014 13:57:49 GMT</pubDate></item><item><title><![CDATA[Reply to Methoden Zeiger für unterschiedliche Rückgabewerte on Sun, 13 Apr 2014 14:31:32 GMT]]></title><description><![CDATA[<p>Lass deine Funktionen doch gleich ein QVariant zurückgeben.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2394377</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2394377</guid><dc:creator><![CDATA[manni66]]></dc:creator><pubDate>Sun, 13 Apr 2014 14:31:32 GMT</pubDate></item><item><title><![CDATA[Reply to Methoden Zeiger für unterschiedliche Rückgabewerte on Sun, 13 Apr 2014 14:46:01 GMT]]></title><description><![CDATA[<p>Das macht keinen Sinn. Die Person ist ja das Model und soll von GUI keine Ahnung haben. Getter a la QVariant getAge() sind da absolut unschön.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2394379</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2394379</guid><dc:creator><![CDATA[Lukan]]></dc:creator><pubDate>Sun, 13 Apr 2014 14:46:01 GMT</pubDate></item><item><title><![CDATA[Reply to Methoden Zeiger für unterschiedliche Rückgabewerte on Sun, 13 Apr 2014 15:18:21 GMT]]></title><description><![CDATA[<p>Lukan schrieb:</p>
<blockquote>
<p>Das macht keinen Sinn. Die Person ist ja das Model und soll von GUI keine Ahnung haben. Getter a la QVariant getAge() sind da absolut unschön.</p>
</blockquote>
<p>Getter an sich sind unschön. Davon abgesehen ist QVariant nicht GUI.</p>
<p>Ich würde allerdings sowieso bei case bleiben.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2394384</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2394384</guid><dc:creator><![CDATA[manni66]]></dc:creator><pubDate>Sun, 13 Apr 2014 15:18:21 GMT</pubDate></item><item><title><![CDATA[Reply to Methoden Zeiger für unterschiedliche Rückgabewerte on Sun, 13 Apr 2014 15:27:54 GMT]]></title><description><![CDATA[<p>Wie du schon gemerkt hast, kannst du Funktionen, die verschiedene Typen zurückgeben, nicht gemeinsam abspeichern.</p>
<p>Du willst das ja aber auch gar nicht, da du ohnehin zu einem String konvertierst. Naheliegend wäre es also, gleich Funktionen zu schreiben, die diese String-Konvertierung für jedes Objekt durchführen.</p>
<pre><code>// Wrapper um Getter, der String zurückgibt
typedef std::function&lt;std::string(const Person&amp;)&gt; Descriptor;

// Das überlädst du für verschiedene Typen X
// Du kannst auch std::to_string() einsetzen und generisch arbeiten
std::string toString(X value);

// Gibt eine Funktion zurück, die für ein bestimmtes Attribut den
// entsprechenden Getter aufruft und das Resultat zu String konvertiert
template &lt;typename R&gt;
Descriptor makeDescriptor(R (Person::*getter)() const)
// getter = Memberfunktionszeiger
{
    return [] (const Person&amp; obj)
    {
        return toString( obj.*getter() );
    };
}

// Anwendung
Descriptor symbol = makeDescriptor(&amp;Person::getSymbol);

Person obj = ...;
std::string val = symbol(obj);
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2394388</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2394388</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Sun, 13 Apr 2014 15:27:54 GMT</pubDate></item><item><title><![CDATA[Reply to Methoden Zeiger für unterschiedliche Rückgabewerte on Sun, 13 Apr 2014 16:07:53 GMT]]></title><description><![CDATA[<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/12954">@Nexus</a>: Das sieht schon mal vielversprechend aus. Wie sieht das ohne C++11 aus (ich verwende kein C++11)?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2394397</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2394397</guid><dc:creator><![CDATA[Lukan]]></dc:creator><pubDate>Sun, 13 Apr 2014 16:07:53 GMT</pubDate></item><item><title><![CDATA[Reply to Methoden Zeiger für unterschiedliche Rückgabewerte on Sun, 13 Apr 2014 16:28:56 GMT]]></title><description><![CDATA[<p>Nicht so gut. Es läuft wohl auf Java hinaus. Naja, wenigstens haben wir Memberfunktionszeiger <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f609.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--winking_face"
      title=";)"
      alt="😉"
    /></p>
<pre><code>struct BaseDescriptor
{
    virtual ~BaseDescriptor() {}
    virtual std::string get(Person&amp; obj) const = 0;
};

template &lt;typename R&gt;
struct ConcreteDescriptor : BaseDescriptor
{
    typedef R (Person::*Getter)() const;

    ConcreteDescriptor(Getter g)
    : getter(g)
    {
    }

    virtual std::string get(Person&amp; obj) const
    {
        return toString( obj.*getter() );
    }

    Getter getter;
};
</code></pre>
<p>+ ein RAII-Wrapper darum herum, damit du das auch vernünftig einsetzen kannst, ohne ständig manuelle Speicherverwaltung zu benutzen. Braucht allerdings auch noch eine <code>clone()</code> -Funktion für Kopiersemantik.</p>
<p>Wenn du TR1 hast, kannst du auch mit <code>std::tr1::function</code> und <code>std::tr1::bind()</code> etwas basteln.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2394401</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2394401</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Sun, 13 Apr 2014 16:28:56 GMT</pubDate></item><item><title><![CDATA[Reply to Methoden Zeiger für unterschiedliche Rückgabewerte on Sun, 13 Apr 2014 16:29:39 GMT]]></title><description><![CDATA[<p>Lukan schrieb:</p>
<blockquote>
<p>Könnte ich in diesen Descripter den getter der Person Klasse hinzufügen, könnte ich einfach sowas schreiben:</p>
<pre><code>return toString( mDescriptor[index.column()].executeGetter() );
</code></pre>
</blockquote>
<p>Der getter kann nur mit einem Objekt aufgerufen werden. Soll das Objekt im Descriptor drin sein oder als Parameter übergeben werden?</p>
<p>Abgesehen davon könntest du sowas machen:</p>
<pre><code>string getName(const Person &amp;p){
    return p.getName();
}

string getAge(const Person &amp;p){
    return to_string(p.getAge());
}
//pro Klasse und Attribut eine Funktion hinzufügen

template &lt;class T&gt;
string getString(int column, const T &amp;t){
    switch(column){
        case 1: return getName(t);
        case 2: return getAge(t);
        //Attribute durchnummerieren
    }
}

QVariant PersonSet::data(const QModelIndex &amp;index, int role) const {
    if (role == Qt::DisplayRole || role == Qt::EditRole) {
        //const Person&amp; person = mPersons[index.row()];
        return getString(mPersons[index.row()]);
</code></pre>
<p>Das sollte nicht so krass viel sein und du musst nur ein einziges Mal den Code schreiben.</p>
<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/12954">@Nexus</a>: Da fehlt eine Klammer Zeile 19: return toString( (obj.*getter)() );</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2394402</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2394402</guid><dc:creator><![CDATA[nwp3]]></dc:creator><pubDate>Sun, 13 Apr 2014 16:29:39 GMT</pubDate></item><item><title><![CDATA[Reply to Methoden Zeiger für unterschiedliche Rückgabewerte on Sun, 13 Apr 2014 17:37:41 GMT]]></title><description><![CDATA[<p>@nwp3: Naja, in deinem Code habe ich ja wieder das riesige switch;)</p>
<p>Ich glaube das was ich wollte geht nicht so wirklich mit C++. Dafür ist C++ wohl zu stark typisiert. Dennoch danke!</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2394414</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2394414</guid><dc:creator><![CDATA[Lukan]]></dc:creator><pubDate>Sun, 13 Apr 2014 17:37:41 GMT</pubDate></item><item><title><![CDATA[Reply to Methoden Zeiger für unterschiedliche Rückgabewerte on Sun, 13 Apr 2014 17:48:26 GMT]]></title><description><![CDATA[<p>Lukan schrieb:</p>
<blockquote>
<p>Ich glaube das was ich wollte geht nicht so wirklich mit C++. Dafür ist C++ wohl zu stark typisiert.</p>
</blockquote>
<p>Ich habe zwei Lösungen gezeigt, für C++98 und C++11. Warum gehen die nicht?</p>
<p>Hast du die Java-Bemerkung etwa wörtlich genommen?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2394417</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2394417</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Sun, 13 Apr 2014 17:48:26 GMT</pubDate></item><item><title><![CDATA[Reply to Methoden Zeiger für unterschiedliche Rückgabewerte on Sun, 13 Apr 2014 18:46:53 GMT]]></title><description><![CDATA[<p>Nexus schrieb:</p>
<blockquote>
<p>Lukan schrieb:</p>
<blockquote>
<p>Ich glaube das was ich wollte geht nicht so wirklich mit C++. Dafür ist C++ wohl zu stark typisiert.</p>
</blockquote>
<p>Ich habe zwei Lösungen gezeigt, für C++98 und C++11. Warum gehen die nicht?</p>
<p>Hast du die Java-Bemerkung etwa wörtlich genommen?</p>
</blockquote>
<p>Weil mir deine Lösung zu komplex ist. Und zusätzlich bräuchte ich noch ein clone() und noch weiteres Gedöns? Ne, das is langsam alles overkill. Dann bleib ich einfach beim switch!</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2394426</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2394426</guid><dc:creator><![CDATA[Lukan]]></dc:creator><pubDate>Sun, 13 Apr 2014 18:46:53 GMT</pubDate></item></channel></rss>