<?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[fehlende Methode wird erst zur Laufzeit bemerkt?]]></title><description><![CDATA[<p>Hi,<br />
ich wollte die Vergleichsoperatoren für boost.any überladen, sodass ein paar bestimmte Typen verglichen werden, während andere Typen eine Exception schmeißen. Warum ich das mache, oder warum ich das mit Makro mache ist hier irrelevant, es funktioniert auch alles gut, nur etwas ist merkwürdig: Das folgende Beispiel kompiliert und der == Operator funktioniert auch problemlos, nur warum kompiliert es eigentlich? Die anderen Vergleichsoperatoren sind für A gar nicht überladen und wenn ich es aufrufe kriege ich eine Segmentation Fault(Laut GDBs Stacktrace ruft sich der == Operator immer und immer wieder selbst auf?).<br />
Wieso kriege ich keine Fehlermeldung vom Compiler sondern eine Segfault?</p>
<pre><code class="language-cpp">class A
  {
  public:
    A(int a) : m_a(a){}
    bool operator==(A const&amp; that){return that.m_a == m_a;}
  private:
    int m_a;
  };

#define COMPARE_TYPE(TYPE1,TYPE2,COMPARE) if(a.type().name() == typeid(TYPE1).name() &amp;&amp; b.type().name() == typeid(TYPE2).name()) \
  return any_cast&lt;TYPE1&gt;(a) COMPARE any_cast&lt;TYPE2&gt;(b); \
else 

#define DYNAMIC_COMPARISON(COMPARE) \
bool operator COMPARE(any const&amp; a, any const&amp; b) \
  { \
  COMPARE_TYPE(int, int,COMPARE) \
  COMPARE_TYPE(A,A,COMPARE) \
  cout &lt;&lt; &quot;Fehler&quot; &lt;&lt; endl; \
  }

DYNAMIC_COMPARISON(==);
DYNAMIC_COMPARISON(!=);
DYNAMIC_COMPARISON(&lt;=);
DYNAMIC_COMPARISON(&lt;);
DYNAMIC_COMPARISON(&gt;);
DYNAMIC_COMPARISON(&gt;=);

int main()
  {
  any a(A(2));
  any b(A(2));
  try
    {
    cout &lt;&lt; (a == b) &lt;&lt; endl;
    }
  catch(...)
    {
    cout &lt;&lt; &quot;uh exception&quot; &lt;&lt; endl;
    }
  }
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/topic/240330/fehlende-methode-wird-erst-zur-laufzeit-bemerkt</link><generator>RSS for Node</generator><lastBuildDate>Tue, 22 Sep 2026 00:44:11 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/240330.rss" rel="self" type="application/rss+xml"/><pubDate>Tue, 05 May 2009 13:25:58 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to fehlende Methode wird erst zur Laufzeit bemerkt? on Tue, 05 May 2009 13:25:58 GMT]]></title><description><![CDATA[<p>Hi,<br />
ich wollte die Vergleichsoperatoren für boost.any überladen, sodass ein paar bestimmte Typen verglichen werden, während andere Typen eine Exception schmeißen. Warum ich das mache, oder warum ich das mit Makro mache ist hier irrelevant, es funktioniert auch alles gut, nur etwas ist merkwürdig: Das folgende Beispiel kompiliert und der == Operator funktioniert auch problemlos, nur warum kompiliert es eigentlich? Die anderen Vergleichsoperatoren sind für A gar nicht überladen und wenn ich es aufrufe kriege ich eine Segmentation Fault(Laut GDBs Stacktrace ruft sich der == Operator immer und immer wieder selbst auf?).<br />
Wieso kriege ich keine Fehlermeldung vom Compiler sondern eine Segfault?</p>
<pre><code class="language-cpp">class A
  {
  public:
    A(int a) : m_a(a){}
    bool operator==(A const&amp; that){return that.m_a == m_a;}
  private:
    int m_a;
  };

#define COMPARE_TYPE(TYPE1,TYPE2,COMPARE) if(a.type().name() == typeid(TYPE1).name() &amp;&amp; b.type().name() == typeid(TYPE2).name()) \
  return any_cast&lt;TYPE1&gt;(a) COMPARE any_cast&lt;TYPE2&gt;(b); \
else 

#define DYNAMIC_COMPARISON(COMPARE) \
bool operator COMPARE(any const&amp; a, any const&amp; b) \
  { \
  COMPARE_TYPE(int, int,COMPARE) \
  COMPARE_TYPE(A,A,COMPARE) \
  cout &lt;&lt; &quot;Fehler&quot; &lt;&lt; endl; \
  }

DYNAMIC_COMPARISON(==);
DYNAMIC_COMPARISON(!=);
DYNAMIC_COMPARISON(&lt;=);
DYNAMIC_COMPARISON(&lt;);
DYNAMIC_COMPARISON(&gt;);
DYNAMIC_COMPARISON(&gt;=);

int main()
  {
  any a(A(2));
  any b(A(2));
  try
    {
    cout &lt;&lt; (a == b) &lt;&lt; endl;
    }
  catch(...)
    {
    cout &lt;&lt; &quot;uh exception&quot; &lt;&lt; endl;
    }
  }
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1705888</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1705888</guid><dc:creator><![CDATA[JustAnotherNoob]]></dc:creator><pubDate>Tue, 05 May 2009 13:25:58 GMT</pubDate></item><item><title><![CDATA[Reply to fehlende Methode wird erst zur Laufzeit bemerkt? on Tue, 05 May 2009 13:50:15 GMT]]></title><description><![CDATA[<p>Also es hat einen Fehler im Code, der womöglich zu undefiniertem Verhalten führen könnte, da nicht alle Kontrollwege im Vergleichsoperator einen Wert zurückgeben. Der Fehler liegt bei diesem Vergleich:</p>
<pre><code class="language-cpp">a.type().name() == typeid(TYPE1).name() &amp;&amp; b.type().name() == typeid(TYPE2).name()
</code></pre>
<p>Im Standard ist nicht definiert, dass die Namen von Typen gleich sind, sondern der Vergleich der <code>type_info</code> Objekte muss gleich sein. Also korrekt wäre das hier:</p>
<pre><code class="language-cpp">a.type() == typeid(TYPE1) &amp;&amp; b.type() == typeid(TYPE2)
</code></pre>
<p>Wenn ich diesen Fehler korrigiere, dann funktioniert dein Code bei mir einwandfrei (VC2008).</p>
<p>Grüssli</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1705912</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1705912</guid><dc:creator><![CDATA[Dravere]]></dc:creator><pubDate>Tue, 05 May 2009 13:50:15 GMT</pubDate></item><item><title><![CDATA[Reply to fehlende Methode wird erst zur Laufzeit bemerkt? on Tue, 05 May 2009 14:12:17 GMT]]></title><description><![CDATA[<p>geändert, ändert aber nichts am Verhalten.<br />
Der Code funktioniert ja auch, nur er sollte meiner Auffassung nach nicht kompilieren, weil &lt;, &lt;=, !=, &gt; und &gt;= für A nicht überladen sind und wenn ich sie aufrufe krieg ich auch eine Segfault.<br />
Oder meinst du mit einwandfrei funktionieren, dass er nicht funktioniert?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1705924</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1705924</guid><dc:creator><![CDATA[JustAnotherNoob]]></dc:creator><pubDate>Tue, 05 May 2009 14:12:17 GMT</pubDate></item><item><title><![CDATA[Reply to fehlende Methode wird erst zur Laufzeit bemerkt? on Tue, 05 May 2009 14:31:38 GMT]]></title><description><![CDATA[<p>Also dein präsentierter Code funktioniert bei mir dann, also den <code>operator ==</code> und es gibt auch ein gültiges Resultat zurück.<br />
Das auch ein <code>operator &gt;=</code> funktioniert, obwohl <code>A</code> keinen definiert hat und es dann zu einer Rekursion kommt, liegt doch auf der Hand? Wieso hat wohl Boost.Any keine Vergleichsoperatoren definiert? Der Konstruktor von Boost.Any ist nicht explizit sondern halt eben implizit. Es gibt keinen <code>operator &gt;=</code> für <code>A</code> , daher wird weitergesucht. Da findet der Kompiler wieder <code>&gt;=</code> für <code>boost::any</code> und durch einen impliziten Cast, kann dieser Operator auch verwendet werden. Alles in Butter, denkt sich da der Kompiler <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>
<p>Grüssli</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1705935</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1705935</guid><dc:creator><![CDATA[Dravere]]></dc:creator><pubDate>Tue, 05 May 2009 14:31:38 GMT</pubDate></item><item><title><![CDATA[Reply to fehlende Methode wird erst zur Laufzeit bemerkt? on Tue, 05 May 2009 14:45:47 GMT]]></title><description><![CDATA[<p>ahh, das macht Sinn.<br />
Aber das heißt dann doch auch, dass wenn ich die Vergleichsoperatoren für boost.any implementiere ich immer einen solchen Fehler bekomme, wenn ich Vergleichsoperatoren für egal welchen Typ aufrufe, der keine Vergleichsoperatoren implementiert hat, oder?<br />
Das ist natürlich unerwünscht, kann ich da irgendwas dran ändern? (vermutlich nicht, also redesign..)</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1705945</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1705945</guid><dc:creator><![CDATA[JustAnotherNoob]]></dc:creator><pubDate>Tue, 05 May 2009 14:45:47 GMT</pubDate></item><item><title><![CDATA[Reply to fehlende Methode wird erst zur Laufzeit bemerkt? on Tue, 05 May 2009 15:46:09 GMT]]></title><description><![CDATA[<p>JustAnotherNoob schrieb:</p>
<blockquote>
<p>Aber das heißt dann doch auch, dass wenn ich die Vergleichsoperatoren für boost.any implementiere ich immer einen solchen Fehler bekomme, wenn ich Vergleichsoperatoren für egal welchen Typ aufrufe, der keine Vergleichsoperatoren implementiert hat, oder?</p>
</blockquote>
<p>Ehm, also wenn ich deine Frage richtig verstanden habe, was ich eigentlich glaube, aber halt nicht ganz sicher bin, da es wohl ein fehlendes Komma hat, was zwar nicht weiter schlimm ist, durchaus aber beim Verständnis stören kann, dann denke ich, bzw. bin eigentlich davon überzeugt, dass die Antwort, auf deine oben gestellte Frage, <strong>JA</strong> lautet.</p>
<p>*SCNR* <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f921.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--clown_face"
      title=":clown:"
      alt="🤡"
    /></p>
<p>JustAnotherNoob schrieb:</p>
<blockquote>
<p>Das ist natürlich unerwünscht, kann ich da irgendwas dran ändern? (vermutlich nicht, also redesign..)</p>
</blockquote>
<p>Boost.Any umschreiben, bzw. den Konstruktor <code>explicit</code> machen. <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title=":)"
      alt="🙂"
    /><br />
Ansonsten fällt mir nicht sehr viel sinnvolles ein. Du könntest natürlich eine Comparison Klasse machen, welche im Konstruktor die beiden Vergleichsobjekte erwartet. Den Konstruktor von dieser Klasse machst du explicit und gibst der Klasse Methoden für die Vergleiche. Ich gebe am besten einen kurzen Quellcode an, aber ich empfinde das nicht als saubere Lösung <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 class="language-cpp">class Comparison
{
private:
  boost::any const&amp; m_lhs;
  boost::any const&amp; m_rhs;

public:
  explicit Comparison(boost::any const&amp; lhs, boost::any const&amp; rhs)
    : m_lhs(lhs)
    , m_rhs(rhs)
  { }

  // Wobei eigentlich das explicit durch die Trennung von den Operatoren,
  // gar nicht mehr nötig wäre ...

public:
  bool is_equal() { /* ... */ }
  bool is_equal_or_greater() { /* ... */ }

  // ... usw
};
</code></pre>
<p>... ich finde es sogar äusserst hässlich <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f603.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--grinning_face_with_big_eyes"
      title=":D"
      alt="😃"
    /></p>
<p>Grüssli</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1705977</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1705977</guid><dc:creator><![CDATA[Dravere]]></dc:creator><pubDate>Tue, 05 May 2009 15:46:09 GMT</pubDate></item></channel></rss>