<?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[operator overloading resolution]]></title><description><![CDATA[<p>Hi,</p>
<p>ich hoffe mir kann jemand helfen.<br />
Ich habe hier ein etwas merkwürdiges Verhalten, dass ich mir nicht so ganz erklären kann.</p>
<pre><code>#include &lt;iostream&gt;
using namespace std;

class C {
private:
	void * p;
public:
	explicit operator bool() const
	{
		if (p == nullptr)
			return false;
	}

	operator void*() const  { return p; }
	operator void**()       { return &amp;p; }
	C() : p(nullptr) {}

};
int main(){

	C c;
	bool b = c;
	void* p = c;
	void** pp = c;

	if (c)
		cout &lt;&lt; &quot;TRUE&quot; &lt;&lt; endl;

	cout &lt;&lt; b &lt;&lt; endl;
	cout &lt;&lt; p &lt;&lt; endl;
	cout &lt;&lt; pp &lt;&lt; endl;

	int lala;
	cin &gt;&gt; lala;
}
</code></pre>
<p>So lange der Operator bool const ist, wird immer der void** Operator genommen.</p>
<p>Könnte mir jemand bitte erklären warum das so ist?</p>
<p>Gruß<br />
-c</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/328630/operator-overloading-resolution</link><generator>RSS for Node</generator><lastBuildDate>Tue, 07 Jul 2026 13:07:07 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/328630.rss" rel="self" type="application/rss+xml"/><pubDate>Mon, 20 Oct 2014 13:11:38 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to operator overloading resolution on Mon, 20 Oct 2014 13:11:38 GMT]]></title><description><![CDATA[<p>Hi,</p>
<p>ich hoffe mir kann jemand helfen.<br />
Ich habe hier ein etwas merkwürdiges Verhalten, dass ich mir nicht so ganz erklären kann.</p>
<pre><code>#include &lt;iostream&gt;
using namespace std;

class C {
private:
	void * p;
public:
	explicit operator bool() const
	{
		if (p == nullptr)
			return false;
	}

	operator void*() const  { return p; }
	operator void**()       { return &amp;p; }
	C() : p(nullptr) {}

};
int main(){

	C c;
	bool b = c;
	void* p = c;
	void** pp = c;

	if (c)
		cout &lt;&lt; &quot;TRUE&quot; &lt;&lt; endl;

	cout &lt;&lt; b &lt;&lt; endl;
	cout &lt;&lt; p &lt;&lt; endl;
	cout &lt;&lt; pp &lt;&lt; endl;

	int lala;
	cin &gt;&gt; lala;
}
</code></pre>
<p>So lange der Operator bool const ist, wird immer der void** Operator genommen.</p>
<p>Könnte mir jemand bitte erklären warum das so ist?</p>
<p>Gruß<br />
-c</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2422978</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2422978</guid><dc:creator><![CDATA[operator - c++]]></dc:creator><pubDate>Mon, 20 Oct 2014 13:11:38 GMT</pubDate></item><item><title><![CDATA[Reply to operator overloading resolution on Mon, 20 Oct 2014 14:03:27 GMT]]></title><description><![CDATA[<p>Das const hinter den Funktionen bedeutet, dass diese Funktionen <s>nur</s> als erstes auf Konstante Objekte aufgerufen werden. Da du aber ein nicht konstantes Objekt casten willst, wird offensichtlich der einzigste Castoperator genommnen, der nicht Const ist und daher am besten passt.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2422981</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2422981</guid><dc:creator><![CDATA[JulianH]]></dc:creator><pubDate>Mon, 20 Oct 2014 14:03:27 GMT</pubDate></item><item><title><![CDATA[Reply to operator overloading resolution on Mon, 20 Oct 2014 13:49:18 GMT]]></title><description><![CDATA[<p>@MrLong: Dein erster Satz ist quatsch.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2422988</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2422988</guid><dc:creator><![CDATA[Columbo]]></dc:creator><pubDate>Mon, 20 Oct 2014 13:49:18 GMT</pubDate></item><item><title><![CDATA[Reply to operator overloading resolution on Mon, 20 Oct 2014 14:05:42 GMT]]></title><description><![CDATA[<p>Mr.Long schrieb:</p>
<blockquote>
<p>Das const hinter den Funktionen bedeutet, dass diese Funktionen <s>nur</s> als erstes auf Konstante Objekte aufgerufen werden.</p>
</blockquote>
<p>Das const hinter der Funktion bedeutet, dass innerhalb der Funktion das Objekt(this) nicht verändert werden kann.</p>
<p>Mir ist nicht ganz klar wieso das Auswirkung auf die overload resolution haben sollte.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2422989</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2422989</guid><dc:creator><![CDATA[operator - c++]]></dc:creator><pubDate>Mon, 20 Oct 2014 14:05:42 GMT</pubDate></item><item><title><![CDATA[Reply to operator overloading resolution on Mon, 20 Oct 2014 14:15:55 GMT]]></title><description><![CDATA[<pre><code>class A
{
public:
	operator bool() const { std::cout &lt;&lt; &quot;A is const&quot; &lt;&lt; std::endl; return false;  }
	operator bool() { std::cout &lt;&lt; &quot;A isn't const&quot; &lt;&lt; std::endl; return true;  }
};
int main()
{
	A a;
	const A c_a;
	static_cast&lt;bool&gt;(a); // A isn't const
	static_cast&lt;bool&gt;(c_a); // A is const
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2422992</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2422992</guid><dc:creator><![CDATA[JulianH]]></dc:creator><pubDate>Mon, 20 Oct 2014 14:15:55 GMT</pubDate></item><item><title><![CDATA[Reply to operator overloading resolution on Mon, 20 Oct 2014 14:28:22 GMT]]></title><description><![CDATA[<p>Der Grund ist folgender. Fuer den ersten Schritt der Overload-Resolution wird die Konvertierung des Rueckgabetyps der Konvertierungsfunktion zum Zieltyp <code>bool</code> , also <code>void**</code> -&gt; <code>bool</code> und <code>bool</code> -&gt; <code>bool</code> , gar nicht beruecksichtigt, sondern nur die Konvertierung des Objektarguments zum Objektparameter:</p>
<p>[over.match.best]/1 schrieb:</p>
<blockquote>
<p>Given these definitions, a viable function F1 is defined to be a better function than another viable function F2 if for all arguments i, ICSi(F1) is not a worse conversion sequence than ICSi(F2), and then<br />
— for some argument <em>j</em>, <code>ICS</code> <em>j</em> <code>(F1)</code> is a better conversion sequence than <code>ICS</code> <em>j</em> <code>(F2)</code> , <strong>or, if not that,</strong><br />
— the context is an initialization by user-defined conversion (see 8.5, 13.3.1.5, and 13.3.1.6) and the standard conversion sequence from the return type of <code>F1</code> to the destination type (i.e., the type of the entity being initialized) is a better conversion sequence than the standard conversion sequence from the return type of <code>F2</code> to the destination type.</p>
</blockquote>
<p>Die Objektparameter sind einmal <code>C&amp;</code> und <code>C const&amp;</code> . Das Objektargument ist <code>c</code> , ein lvalue vom Typ <code>C</code> .<br />
Fuer die Konvertierung gilt</p>
<blockquote>
<p>Standard conversion sequence <code>S1</code> is a better conversion sequence than standard conversion sequence <code>S2</code> if<br />
[...]<br />
— <code>S1</code> and <code>S2</code> are reference bindings (8.5.3), and the types to which the references refer are the same type except for top-level cv-qualifiers, and the type to which the reference initialized by S2 refers is more cv-qualified than the type to which the reference initialized by <code>S1</code> refers.</p>
</blockquote>
<p>Das heisst kurz gesagt: <code>operator void**</code> ist bei der Konvertierung des Objektarguments besser, daher wird die Konvertierung des Rueckgabetyps (die zweite standard conversion sequence) gar nicht erst beruecksichtigt.<br />
Erst wenn beide Objektparameter gleich sind, also wenn du <code>operator bool</code> non- <code>const</code> machst, kommt die zweite standard conversion sequence ueberhaupt ins Spiel: Und offensichtlich ist <code>bool</code> -&gt; bool besser als <code>void**</code> -&gt; <code>bool</code> .</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2422993</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2422993</guid><dc:creator><![CDATA[Columbo]]></dc:creator><pubDate>Mon, 20 Oct 2014 14:28:22 GMT</pubDate></item><item><title><![CDATA[Reply to operator overloading resolution on Mon, 20 Oct 2014 14:28:11 GMT]]></title><description><![CDATA[<p>n3337 schrieb:</p>
<blockquote>
<p>13.3.3 Best viable function [over.match.best]<br />
1 Define ICSi(F) as follows:<br />
— if F is a static member function, ICS1 (F) is defined such that ICS1 (F) is neither better nor worse than<br />
ICS1 (G) for any function G, and, symmetrically, ICS1 (G) is neither better nor worse than ICS1 (F)133;<br />
otherwise,<br />
— let ICSi(F) denote the implicit conversion sequence that converts the i-th argument in the list to the<br />
type of the i-th parameter of viable function F. 13.3.3.1 defines the implicit conversion sequences and<br />
13.3.3.2 defines what it means for one implicit conversion sequence to be a better conversion sequence<br />
or worse conversion sequence than another.<br />
Given these definitions, a viable function F1 is defined to be a better function than another viable function<br />
F2 if for all arguments i, ICSi(F1) is not a worse conversion sequence than ICSi(F2), and then<br />
— <strong>for some argument j, ICSj(F1) is a better conversion sequence than ICSj(F2)</strong>, or, <em>if not that</em>,<br />
— <em>the context is an initialization by user-defined conversion (see 8.5, 13.3.1.5, and 13.3.1.6) and the<br />
standard conversion sequence from the return type of F1 to the destination type (i.e., the type of the<br />
entity being initialized) is a better conversion sequence than the standard conversion sequence from<br />
the return type of F2 to the destination type.</em> [...]</p>
</blockquote>
<p>Bei der Auswahl der passenden Konvertierungsfunktion wird also (gedanklich) Überladungsauflösung zweimal durchgeführt.<br />
Nachdem erst einmal alle potentiellen Kandidaten erfasst wurden, also z.B. in</p>
<pre><code class="language-cpp">bool b = c;
</code></pre>
<p>alle Operatoren ausser dem mit explicit markierten, betrachten wir zunächst die notwendige Konvertierung auf dem Argument c (in den jeweiligen Objektparameter), um die Funktion aufrufen zu können. die const-Überladungen benötigen dafür jeweils eine Qualifikationskonvertierung C -&gt; const C, die void**-Variante kommt mit der sog. identischen Konvertierung aus. Alle diese Standardkonvertierungen haben zwar den selben Rang (=Exact Match), allerdings ist die identische Konvertierung eine echte Untersequenz der Qualifikationskonvertierung und folglich besser. Damit sind die const-Überladungen bereits eliminiert, und der zweite Schritt ist gar nicht mehr durchzuführen.</p>
<p>Das ist also nicht viel anders als gewöhnliche Überladungsauflösung:<br />
1. Schritt: aufzählen aller möglichen Konvertierungswege,<br />
2. Schritt: Auswahl der am leichtesten aufrufbaren Funktion, (gewöhnliche Überladung)<br />
3. Schritt: falls 2. Schritt mehrere Kandidaten hinterlässt, Auswahl der Funktion mit der besten Konvertierung des Ergebnisses in den Zieltyp.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2422994</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2422994</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Mon, 20 Oct 2014 14:28:11 GMT</pubDate></item><item><title><![CDATA[Reply to operator overloading resolution on Mon, 20 Oct 2014 14:29:53 GMT]]></title><description><![CDATA[<p>Also hat die Constness eines Castoperators groesseres Gewicht als der tatsaechliche Returntyp? Und das, obwohl auf diesem Weg eine zusaetzliche implizite Konvertierung erforderlich ist? Und obwohl es ueberhaupt kein Problem waere, &quot;operator bool() const&quot; auf einem Nicht-const-Objekt aufzurufen?<br />
Wow. <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f62e.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--face_with_open_mouth"
      title=":open_mouth:"
      alt="😮"
    /></p>
<p>Zusaetzliches Denkfutter:<br />
Wenn der Typ von void zu int geaendert wird, dann findet der Compiler auch &quot;operator int*() const&quot;. Bei Verwendung von void* wird auch in diesem Fall &quot;operator void**()&quot; aufgerufen. Warum?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2422995</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2422995</guid><dc:creator><![CDATA[surprisee]]></dc:creator><pubDate>Mon, 20 Oct 2014 14:29:53 GMT</pubDate></item><item><title><![CDATA[Reply to operator overloading resolution on Mon, 20 Oct 2014 14:37:18 GMT]]></title><description><![CDATA[<blockquote>
<p>Also hat die Constness eines Castoperators groesseres Gewicht als der tatsaechliche Returntyp?</p>
</blockquote>
<p>Grob gesagt.</p>
<blockquote>
<p>Wenn der Typ von void zu int geaendert wird, dann findet der Compiler auch &quot;operator int*() const&quot;. Bei Verwendung von void* wird auch in diesem Fall &quot;operator void**()&quot; aufgerufen. Warum?</p>
</blockquote>
<p>Mir ist nicht ganz klar was du meinst. Alle meine Interpretationen konnte ich (zumindest mit Clang) nicht nachvollziehen. Code?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2423001</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2423001</guid><dc:creator><![CDATA[Columbo]]></dc:creator><pubDate>Mon, 20 Oct 2014 14:37:18 GMT</pubDate></item><item><title><![CDATA[Reply to operator overloading resolution on Mon, 20 Oct 2014 14:39:33 GMT]]></title><description><![CDATA[<p>Vielen Dank, Camper und Arcoth für die ausführliche Beschreibung, dass habe ich gesucht!<br />
Nochmal Vielen Dank. <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f44d.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--thumbs_up"
      title=":+1:"
      alt="👍"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/2423004</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2423004</guid><dc:creator><![CDATA[operator - c++]]></dc:creator><pubDate>Mon, 20 Oct 2014 14:39:33 GMT</pubDate></item><item><title><![CDATA[Reply to operator overloading resolution on Mon, 20 Oct 2014 14:42:21 GMT]]></title><description><![CDATA[<blockquote>
<p>die const-Überladungen benötigen dafür jeweils eine Qualifikationskonvertierung C -&gt; const C, die void**-Variante kommt mit der sog. identischen Konvertierung aus.</p>
</blockquote>
<p>Die Argumentation ist falsch. Qualifikationskonvertierungen gibt es nur fuer Zeiger. <code>C -&gt; const C</code> ist genau so gut wie <code>C -&gt; C</code> . Mein zweites Zitat ist der richtige Grund.</p>
<p>Edit: Ich habs doch gesagt! Du bist meschugge!</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2423006</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2423006</guid><dc:creator><![CDATA[Columbo]]></dc:creator><pubDate>Mon, 20 Oct 2014 14:42:21 GMT</pubDate></item><item><title><![CDATA[Reply to operator overloading resolution on Mon, 20 Oct 2014 14:46:26 GMT]]></title><description><![CDATA[<p>Arcoth schrieb:</p>
<blockquote>
<blockquote>
<p>Wenn der Typ von void zu int geaendert wird, dann findet der Compiler auch &quot;operator int*() const&quot;. Bei Verwendung von void* wird auch in diesem Fall &quot;operator void**()&quot; aufgerufen. Warum?</p>
</blockquote>
<p>Mir ist nicht ganz klar was du meinst. Alle meine Interpretationen konnte ich (zumindest mit Clang) nicht nachvollziehen. Code?</p>
</blockquote>
<p>Im originalen Code einfach alle &quot;void&quot;s durch &quot;int&quot;s ersetzen. Weiss nicht was Clang dazu sagt, aber VS und g++ machen das selbe. <a href="http://ideone.com/XbWpKh" rel="nofollow">http://ideone.com/XbWpKh</a></p>
]]></description><link>https://www.c-plusplus.net/forum/post/2423009</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2423009</guid><dc:creator><![CDATA[surprisee]]></dc:creator><pubDate>Mon, 20 Oct 2014 14:46:26 GMT</pubDate></item><item><title><![CDATA[Reply to operator overloading resolution on Mon, 20 Oct 2014 14:53:55 GMT]]></title><description><![CDATA[<p>Arcoth schrieb:</p>
<blockquote>
<blockquote>
<p>die const-Überladungen benötigen dafür jeweils eine Qualifikationskonvertierung C -&gt; const C, die void**-Variante kommt mit der sog. identischen Konvertierung aus.</p>
</blockquote>
<p>Die Argumentation ist falsch. Qualifikationskonvertierungen gibt es nur fuer Zeiger. <code>C -&gt; const C</code> ist genau so gut wie <code>C -&gt; C</code> . Mein zweites Zitat ist der richtige Grund.</p>
</blockquote>
<p>Versuch mal ein Beispiel zu konstruieren, in dem diese Argumentation zu einem anderen Ergebnis führt (also im Vergleich zu: Binden an eine Referenz mit mehr cv-Qualifikation wird wie eine Qualifikationskonvertierung behandelt). Ich bin mir der Standardtextes durchaus bewusst, sehe aber keinen Grund, doppelt soviel zu schreiben, bloss weil der Standardtext unnötig umständlich ist.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2423012</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2423012</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Mon, 20 Oct 2014 14:53:55 GMT</pubDate></item><item><title><![CDATA[Reply to operator overloading resolution on Mon, 20 Oct 2014 14:56:10 GMT]]></title><description><![CDATA[<p>surprisee schrieb:</p>
<blockquote>
<p>Arcoth schrieb:</p>
<blockquote>
<blockquote>
<p>Wenn der Typ von void zu int geaendert wird, dann findet der Compiler auch &quot;operator int*() const&quot;. Bei Verwendung von void* wird auch in diesem Fall &quot;operator void**()&quot; aufgerufen. Warum?</p>
</blockquote>
<p>Mir ist nicht ganz klar was du meinst. Alle meine Interpretationen konnte ich (zumindest mit Clang) nicht nachvollziehen. Code?</p>
</blockquote>
<p>Im originalen Code einfach alle &quot;void&quot;s durch &quot;int&quot;s ersetzen. Weiss nicht was Clang dazu sagt, aber VS und g++ machen das selbe. <a href="http://ideone.com/XbWpKh" rel="nofollow">http://ideone.com/XbWpKh</a></p>
</blockquote>
<p>void** kann nat. in void* konvertiert werden, denn jeder (cv-unqualifizierte) Objektzeiger kann nach void* konvertiert werden.<br />
Eine Konvertierung int** -&gt; int* gibt es dagegen nicht.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2423013</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2423013</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Mon, 20 Oct 2014 14:56:10 GMT</pubDate></item><item><title><![CDATA[Reply to operator overloading resolution on Mon, 20 Oct 2014 15:08:50 GMT]]></title><description><![CDATA[<p>camper schrieb:</p>
<blockquote>
<p>void** kann nat. in void* konvertiert werden, denn jeder (cv-unqualifizierte) Objektzeiger kann nach void* konvertiert werden.<br />
Eine Konvertierung int** -&gt; int* gibt es dagegen nicht.</p>
</blockquote>
<p>Oh Mann, da kam ja einiges zusammen. Alles standardkonform, aber in der Praxis reichlich kontraintuitiv und zu subtilen Fehlern fuehrend. ZB liefert die Verwendung im bool-Kontext a la &quot;if (c)&quot; immer true zurueck, da operator void**() verwendet wird und die Membervariable natuerlich immer an einer gueltigen Speicheradresse liegt... (Der Code sieht im Original nat. etwas anders aus, ist eine Wrapperklasse um Windows API HANDLEs, die eben als void* bzw. void** #definiert sind.)</p>
<p>Auch von mir nochmal vielen Dank, camper &amp; Arcoth!</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2423021</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2423021</guid><dc:creator><![CDATA[surprisee]]></dc:creator><pubDate>Mon, 20 Oct 2014 15:08:50 GMT</pubDate></item></channel></rss>