<?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[Überladung von Konvertierungsoperatoren mit template]]></title><description><![CDATA[<p>Tach zusammen. Folgender Code:</p>
<pre><code class="language-cpp">struct S {};

struct Testable
{
  template &lt;class T&gt;
  operator T() /* = delete */;       //a)

  operator bool() {return true;}     //b)
};

int main()
{
  Testable t;
  bool b = t;  //1)
  int i = t;   //2)
  S s = t;     //3)
};
</code></pre>
<p>Meine Erwartung wäre folgende:</p>
<ol>
<li>ruft b)</li>
<li>ruft a)&lt;int&gt;, -&gt; Fehler (Linker bzw. deleted)</li>
<li>ruft a)&lt;S&gt;, -&gt; Fehler (Linker bzw. deleted)</li>
</ol>
<p>Verhalten MSVC: wie erwartet.<br />
Verhalten gcc-4.5.1 (<a href="http://ideone.com" rel="nofollow">ideone.com</a>): 2) ruft b), kein Fehler!</p>
<p>Welches ist richtig?</p>
<p>Der Fall für Fortgeschrittene:</p>
<pre><code class="language-cpp">#include &lt;type_traits&gt;  

struct S {};

struct Testable
{
  template &lt;class T&gt;
  operator typename std::enable_if&lt;std::is_convertible&lt;bool, T&gt;::value, T&gt;::type () /* = delete */;       //a)

  operator bool() {return true;} //b)
};

int main()
{
  Testable t;
  bool b = t; //1)
  int i = t;  //2)
  S s = t;    //3)
};
</code></pre>
<p>Meine Erwartung:</p>
<ol>
<li>ruft b)</li>
<li>ruft a) -&gt; Fehler (Linker/deleted)</li>
<li>Compilerfehler, keine Konvertierung gefunden.</li>
</ol>
<p>Verhalten MSVC und gcc-4.5.1 (<a href="http://ideone.com" rel="nofollow">ideone.com</a>): 2) ruft b), kein Fehler!</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/295100/überladung-von-konvertierungsoperatoren-mit-template</link><generator>RSS for Node</generator><lastBuildDate>Sat, 15 Aug 2026 14:30:27 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/295100.rss" rel="self" type="application/rss+xml"/><pubDate>Mon, 07 Nov 2011 09:26:56 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Überladung von Konvertierungsoperatoren mit template on Mon, 07 Nov 2011 09:31:59 GMT]]></title><description><![CDATA[<p>Tach zusammen. Folgender Code:</p>
<pre><code class="language-cpp">struct S {};

struct Testable
{
  template &lt;class T&gt;
  operator T() /* = delete */;       //a)

  operator bool() {return true;}     //b)
};

int main()
{
  Testable t;
  bool b = t;  //1)
  int i = t;   //2)
  S s = t;     //3)
};
</code></pre>
<p>Meine Erwartung wäre folgende:</p>
<ol>
<li>ruft b)</li>
<li>ruft a)&lt;int&gt;, -&gt; Fehler (Linker bzw. deleted)</li>
<li>ruft a)&lt;S&gt;, -&gt; Fehler (Linker bzw. deleted)</li>
</ol>
<p>Verhalten MSVC: wie erwartet.<br />
Verhalten gcc-4.5.1 (<a href="http://ideone.com" rel="nofollow">ideone.com</a>): 2) ruft b), kein Fehler!</p>
<p>Welches ist richtig?</p>
<p>Der Fall für Fortgeschrittene:</p>
<pre><code class="language-cpp">#include &lt;type_traits&gt;  

struct S {};

struct Testable
{
  template &lt;class T&gt;
  operator typename std::enable_if&lt;std::is_convertible&lt;bool, T&gt;::value, T&gt;::type () /* = delete */;       //a)

  operator bool() {return true;} //b)
};

int main()
{
  Testable t;
  bool b = t; //1)
  int i = t;  //2)
  S s = t;    //3)
};
</code></pre>
<p>Meine Erwartung:</p>
<ol>
<li>ruft b)</li>
<li>ruft a) -&gt; Fehler (Linker/deleted)</li>
<li>Compilerfehler, keine Konvertierung gefunden.</li>
</ol>
<p>Verhalten MSVC und gcc-4.5.1 (<a href="http://ideone.com" rel="nofollow">ideone.com</a>): 2) ruft b), kein Fehler!</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2141513</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2141513</guid><dc:creator><![CDATA[pumuckl]]></dc:creator><pubDate>Mon, 07 Nov 2011 09:31:59 GMT</pubDate></item><item><title><![CDATA[Reply to Überladung von Konvertierungsoperatoren mit template on Mon, 07 Nov 2011 13:15:36 GMT]]></title><description><![CDATA[<p>pumuckl schrieb:</p>
<blockquote>
<p>Tach zusammen. Folgender Code:</p>
<pre><code class="language-cpp">struct S {};
 
struct Testable
{
  template &lt;class T&gt;
  operator T() /* = delete */;       //a)
 
  operator bool() {return true;}     //b)
};
 
int main()
{
  Testable t;
  bool b = t;  //1)
  int i = t;   //2)
  S s = t;     //3)
};
</code></pre>
<p>Meine Erwartung wäre folgende:</p>
<ol>
<li>ruft b)</li>
<li>ruft a)&lt;int&gt;, -&gt; Fehler (Linker bzw. deleted)</li>
<li>ruft a)&lt;S&gt;, -&gt; Fehler (Linker bzw. deleted)</li>
</ol>
<p>Verhalten MSVC: wie erwartet.<br />
Verhalten gcc-4.5.1 (<a href="http://ideone.com" rel="nofollow">ideone.com</a>): 2) ruft b), kein Fehler!</p>
<p>Welches ist richtig?</p>
</blockquote>
<p>Ich würde auch das Ergebnis von msvc erwarten, Online-Comeau stimmt allerdings mit g++ überein (für den Online-Comeau habe ich { return 0/(sizeof(T)==0); } für operator T() verwendet, ein paar zusätzliche Warnungen entstehen dabei natürlich). Eine implite Konvertierungssequenz mit nutzerdefiniertem Konvertierungsoperator ist besser als eine andere solche Sequenz, wenn die anschließende Standardkonvertierungssequenz einen besseren Rang hat.<br />
In</p>
<pre><code class="language-cpp">int i = t;
</code></pre>
<p>ist diese zweite Konvertierungssequenz ein &quot;exact match&quot; für operator T mit T=int, und &quot;promotion&quot; für operator bool, letzteres ist schlechter (13.3.3.1.2). Ich habe also keine Erklärung für das Verhalten von g++.</p>
<p>pumuckl schrieb:</p>
<blockquote>
<p>Der Fall für Fortgeschrittene:</p>
<pre><code class="language-cpp">#include &lt;type_traits&gt;  

struct S {};
 
struct Testable
{
  template &lt;class T&gt;
  operator typename std::enable_if&lt;std::is_convertible&lt;bool, T&gt;::value, T&gt;::type () /* = delete */;       //a)
 
  operator bool() {return true;} //b)
};
 
int main()
{
  Testable t;
  bool b = t; //1)
  int i = t;  //2)
  S s = t;    //3)
};
</code></pre>
<p>Meine Erwartung:</p>
<ol>
<li>ruft b)</li>
<li>ruft a) -&gt; Fehler (Linker/deleted)</li>
<li>Compilerfehler, keine Konvertierung gefunden.</li>
</ol>
<p>Verhalten MSVC und gcc-4.5.1 (<a href="http://ideone.com" rel="nofollow">ideone.com</a>): 2) ruft b), kein Fehler!</p>
</blockquote>
<p>Der Fall ist einfach.</p>
<pre><code class="language-cpp">typename std::enable_if&lt;std::is_convertible&lt;bool, T&gt;::value, T&gt;::type
</code></pre>
<p>ist kein deduzierbarer Kontext, also kann kein T deduziert werden, folglich wird auch keine Spezialiserung dieses Templates teil des Überladungssets. Das macht sich unter anderem auch dadruch bemerkbar, dass die Fehlermeldung für 3) diesmal etwas anders aussieht.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2141593</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2141593</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Mon, 07 Nov 2011 13:15:36 GMT</pubDate></item><item><title><![CDATA[Reply to Überladung von Konvertierungsoperatoren mit template on Mon, 07 Nov 2011 13:35:47 GMT]]></title><description><![CDATA[<p>Gut, für den zweiten Fall wäre also sowas besser:</p>
<pre><code class="language-cpp">#include &lt;type_traits&gt;  
#include &lt;iostream&gt;

struct S {};

struct Testable
{
  template &lt;class T, class = typename std::enable_if&lt;std::is_convertible&lt;bool, T&gt;::value, T&gt;::type&gt;
  operator T() /* = delete */;       //a)

  operator bool() {std::cout &lt;&lt; &quot;!\n&quot;; return true;} //b)
};

int main()
{
  Testable t;
  bool b = t; //1)
  int i = t;  //2)
  //S s = t;    //3)
};
</code></pre>
<p>Was nach C++0x-Standard zwar das gewünschte Verhalten erzeugen sollte, allerdings daran scheitert, dass GCC hier wieder die Overload resolution verhaut und MSVC noch keine default-Template-Argumente für Funktionstemplates implementiert hat. Gnarf.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2141600</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2141600</guid><dc:creator><![CDATA[pumuckl]]></dc:creator><pubDate>Mon, 07 Nov 2011 13:35:47 GMT</pubDate></item><item><title><![CDATA[Reply to Überladung von Konvertierungsoperatoren mit template on Mon, 07 Nov 2011 13:45:48 GMT]]></title><description><![CDATA[<p>Spricht etwas dagegen, das Template für bool explizit zu spezialisieren?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2141604</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2141604</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Mon, 07 Nov 2011 13:45:48 GMT</pubDate></item><item><title><![CDATA[Reply to Überladung von Konvertierungsoperatoren mit template on Mon, 07 Nov 2011 14:11:47 GMT]]></title><description><![CDATA[<p>camper schrieb:</p>
<blockquote>
<p>Spricht etwas dagegen, das Template für bool explizit zu spezialisieren?</p>
</blockquote>
<p>Erstens, dass ich Spezialisierungen von Funktionstemplates nicht so prall finde (ok, schwacher Grund).<br />
Zweitens, dass die ganze enable-if-Geschichte dazu dienen soll, eventuelle andere Konvertierungen mit folgender automatischer Konvertierung zu erlauben, Beispiel:</p>
<pre><code class="language-cpp">struct Testable
{
  /* bool, T wie gehabt, oder eben als Spezialisierung */
  operator float() { return 1.0; }
};

/* ... */ 
Testable t;
double d = t; //knallt, wenn das template nicht enable_if'd ist, weil dann t&lt;double&gt; zieht, nicht op float -&gt; promotion
bool b = t; //macht im GCC Probleme, wenn das Template nicht an der Overload resolution teilnimmt. Meh.
</code></pre>
<p>Das würde natürlich das enable_if noch mit einem !is_floating_point odr sowas aufblähen, aber ich denke man merkt was ich meine.</p>
<p>Drittens: Autsch: Wie sähe die Spezialisierung für das Template aus?? Ich habs nicht hinbekommen...</p>
<pre><code class="language-cpp">struct Testable
{
  template &lt;class T, typename std::enable_if&lt;std::is_convertible&lt;bool, T&gt;::value, bool&gt;::type = true&gt;
  operator T() = delete;       //a)

  template &lt;&gt;
  //operator bool&lt;bool, true&gt;()  //1)
  //operator bool()              //2)
  //operator &lt;bool, true&gt; bool() //3)
  {return &quot;whatever&quot;;}
};
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2141622</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2141622</guid><dc:creator><![CDATA[pumuckl]]></dc:creator><pubDate>Mon, 07 Nov 2011 14:11:47 GMT</pubDate></item><item><title><![CDATA[Reply to Überladung von Konvertierungsoperatoren mit template on Mon, 07 Nov 2011 14:19:39 GMT]]></title><description><![CDATA[<p>pumuckl schrieb:</p>
<blockquote>
<p>Drittens: Autsch: Wie sähe die Spezialisierung für das Template aus?? Ich habs nicht hinbekommen...</p>
</blockquote>
<p>Immer außerhalb der Klasse.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2141630</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2141630</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Mon, 07 Nov 2011 14:19:39 GMT</pubDate></item><item><title><![CDATA[Reply to Überladung von Konvertierungsoperatoren mit template on Mon, 07 Nov 2011 15:42:41 GMT]]></title><description><![CDATA[<p>C++03 schrieb:</p>
<blockquote>
<p>13.3.3 Best Viable Function [over.match.best]<br />
...<br />
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 j, ICSj(F1) is a better conversion sequence than ICSj(F2), or, if not that,<br />
— F1 is a non-template function and F2 is a function template specialization, or, if not that,<br />
— F1 and F2 are function template specializations, and the function template for F1 is more specialized than the template for F2 according to the partial ordering rules described in 14.5.5.2, or, if not that,<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 F1 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 F2 to the destination type. [Example:<br />
struct A {<br />
A();<br />
operator int();<br />
operator double();<br />
} a;<br />
int i = a; // a.operator int() followed by no conversion<br />
// is better than a.operator double() followed by<br />
// a conversion to int<br />
float x = a; // ambiguous: both possibilities require conversions,<br />
// and neither is better than the other<br />
—end example]</p>
</blockquote>
<p>n3290 schrieb:</p>
<blockquote>
<p>13.3.3 Best viable function [over.match.best]<br />
...<br />
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 j, ICSj(F1) is a better conversion sequence than ICSj(F2), or, if not that,<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 F1 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 F2 to the destination type. [ Example:<br />
struct A {<br />
A();<br />
operator int();<br />
operator double();<br />
} a;<br />
int i = a; // a.operator int() followed by no conversion<br />
// is better than a.operator double() followed by<br />
// a conversion to int<br />
float x = a; // ambiguous: both possibilities require conversions,<br />
// and neither is better than the other<br />
— F1 is a non-template function and F2 is a function template specialization, or, if not that,<br />
— F1 and F2 are function template specializations, and the function template for F1 is more specialized than the template for F2 according to the partial ordering rules described in 14.5.6.2.</p>
</blockquote>
<p>Die Reihenfolge, in der die Alternativen abgearbeitet werden, hat sich offenbar geändert. msvc macht es praktisch so wie im neuen Standard vorgesehen, g++ benutzt (noch) die alten Regeln. Nach den alten Regeln führt allein die Tatsache, dass eine Funktion eine Templatefunktion ist und die andere nicht zur Entscheidung, ein Vergleich der Konvertierungsränge findet gar nicht statt.</p>
<p>Edit: Nachdem klar ist, wonach gesucht werden muss, findet sich auch der zugehörige <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#495" rel="nofollow">Report</a> schnell.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2141667</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2141667</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Mon, 07 Nov 2011 15:42:41 GMT</pubDate></item></channel></rss>