<?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[sfinae und iterator_traits]]></title><description><![CDATA[<p>hab gerade ein dummes problem, folgender code kompiliert nicht:</p>
<pre><code>#include &lt;iterator&gt;
template&lt;typename T&gt;
struct checker
{
	typedef char bigger[2];

	template&lt;typename U&gt;
	static char check(typename std::iterator_traits&lt;U&gt;::value_type*);
	template&lt;typename U&gt;
	static bigger&amp; check(...);

	static const bool result = sizeof(check&lt;T&gt;(0)) == sizeof(char);
};
int main()
{
	checker&lt;int&gt;::result;
}
</code></pre>
<p>wie kann ich in c++03 prüfen, ob std::iterator_traits&lt;U&gt;::value_type existiert?</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/328505/sfinae-und-iterator_traits</link><generator>RSS for Node</generator><lastBuildDate>Tue, 07 Jul 2026 12:21:02 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/328505.rss" rel="self" type="application/rss+xml"/><pubDate>Mon, 13 Oct 2014 13:39:23 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to sfinae und iterator_traits on Mon, 13 Oct 2014 13:39:23 GMT]]></title><description><![CDATA[<p>hab gerade ein dummes problem, folgender code kompiliert nicht:</p>
<pre><code>#include &lt;iterator&gt;
template&lt;typename T&gt;
struct checker
{
	typedef char bigger[2];

	template&lt;typename U&gt;
	static char check(typename std::iterator_traits&lt;U&gt;::value_type*);
	template&lt;typename U&gt;
	static bigger&amp; check(...);

	static const bool result = sizeof(check&lt;T&gt;(0)) == sizeof(char);
};
int main()
{
	checker&lt;int&gt;::result;
}
</code></pre>
<p>wie kann ich in c++03 prüfen, ob std::iterator_traits&lt;U&gt;::value_type existiert?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2421987</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2421987</guid><dc:creator><![CDATA[hanstroll123]]></dc:creator><pubDate>Mon, 13 Oct 2014 13:39:23 GMT</pubDate></item><item><title><![CDATA[Reply to sfinae und iterator_traits on Mon, 13 Oct 2014 13:53:35 GMT]]></title><description><![CDATA[<p>Edit: Muss ich nochmal recherchieren.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2421989</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2421989</guid><dc:creator><![CDATA[Columbo]]></dc:creator><pubDate>Mon, 13 Oct 2014 13:53:35 GMT</pubDate></item><item><title><![CDATA[Reply to sfinae und iterator_traits on Mon, 13 Oct 2014 14:00:38 GMT]]></title><description><![CDATA[<p>Wieso sollte es nicht existieren?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2421990</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2421990</guid><dc:creator><![CDATA[Nathan]]></dc:creator><pubDate>Mon, 13 Oct 2014 14:00:38 GMT</pubDate></item><item><title><![CDATA[Reply to sfinae und iterator_traits on Mon, 13 Oct 2014 14:06:23 GMT]]></title><description><![CDATA[<p>hanstroll123 schrieb:</p>
<blockquote>
<p>wie kann ich in c++03 prüfen, ob std::iterator_traits&lt;U&gt;::value_type existiert?</p>
</blockquote>
<p>value_type existiert immer (es sei, man spezialisiert selbst und lässt es weg). Und genau das ist dein Problem:<br />
unspezialisiert verweist iteratur_traits&lt;T&gt;::value_type auf T::value_type, und wenn jenes nicht existiert, ist der entstehende Fehler nicht mehr im &quot;Kontext der Instantiierung&quot;, und somit greift SFINAE nicht.<br />
Eine Lösung habe ich allerdings auch nicht parat, evtl. beschreibst du mal, wass du tun willst, und es findet sich ein anderer Weg?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2421991</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2421991</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Mon, 13 Oct 2014 14:06:23 GMT</pubDate></item><item><title><![CDATA[Reply to sfinae und iterator_traits on Mon, 13 Oct 2014 14:17:38 GMT]]></title><description><![CDATA[<blockquote>
<p>ob std::iterator_traits&lt;U&gt;::value_type existiert?</p>
</blockquote>
<p>Der existiert immer. <code>iterator_traits</code> ' Primärtemplate ist nicht leer sondern verweist einfach auf die Member des Template-Arguments.</p>
<blockquote>
<p>unspezialisiert verweist iteratur_traits&lt;T&gt;::value_type auf T::value_type, und wenn jenes nicht existiert, ist der entstehende Fehler nicht mehr im &quot;Kontext der Instantiierung&quot;, und somit greift SFINAE nicht.</p>
</blockquote>
<p>Das ist fast das was ich geschrieben und dann verworfen habe (hast du das etwa abgeschrieben?). Denn es ist die falsche Erklärung, schließlich existiert die Regel genau so in C++11 und mit -std=c++11 funktioniert es plötzlich, sowohl mit Clang als auch GCC. (Ich denke es gibt irgendwo einen Defekt-Report o.ä., den ich gerade suche)</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2421993</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2421993</guid><dc:creator><![CDATA[Columbo]]></dc:creator><pubDate>Mon, 13 Oct 2014 14:17:38 GMT</pubDate></item><item><title><![CDATA[Reply to sfinae und iterator_traits on Mon, 13 Oct 2014 14:21:09 GMT]]></title><description><![CDATA[<p>das war etwas unglücklich formuliert. der typ existiert stets, U::value_type aber eben nicht immer (sofern mal keine überladung von iterator_traits greift).</p>
<p>was ich tun möchte ist zwei versionen einer funktion anzubieten (so quasi überladen), abhängig davon was der dritte parameter ist. naiv sieht das in etwa so aus:</p>
<pre><code>template&lt;typename T, typename U&gt;
void f(T, T, U)
{
}
template&lt;typename T&gt;
void f(T, T, typename std::iterator_traits&lt;T&gt;::value_type)
{
}
</code></pre>
<p>wenn U implizit in std::iterator_traits&lt;T&gt;::value_type konvertierbar ist, so möchte ich die zweite version benutzen, ansonsten die erste.<br />
dies funktioniert jedoch nicht so einfach, da U und std::iterator_traits&lt;T&gt;::value_type &quot;gleichrangig&quot; sind (was ich auch nicht verstehe btw; wenn der parameter vom typen int oder so wäre, dann würde dieser selbstverständlich vorgezogen werden; hier beim abhängigen namen ist das nicht der fall...). wenn das gezeigte konstrukt aus dem op funktionieren würde, so könnte ich mit trivialen mitteln eine lösung schreiben (erst prüfen ob der typ existiert, dann prüfen ob implizit konvertierbar).</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2421995</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2421995</guid><dc:creator><![CDATA[hanstroll123]]></dc:creator><pubDate>Mon, 13 Oct 2014 14:21:09 GMT</pubDate></item><item><title><![CDATA[Reply to sfinae und iterator_traits on Mon, 13 Oct 2014 15:03:10 GMT]]></title><description><![CDATA[<blockquote>
<p>dies funktioniert jedoch nicht so einfach, da U und std::iterator_traits&lt;T&gt;::value_type &quot;gleichrangig&quot; sind (was ich auch nicht verstehe btw; wenn der parameter vom typen int oder so wäre, dann würde dieser selbstverständlich vorgezogen werden; hier beim abhängigen namen ist das nicht der fall...).</p>
</blockquote>
<p>~~Eigentlich sollte das zweite Template spezialisierter sein. Offenbar gibt es irgendwo in C++98 eine Regel die besagt dass partial ordering non-deduced contexts nicht beachtet.~~Nein, auch laut C++11 ist keines spezialisierter als das andere, schließlich ist die Deduzierung in beide Richtungen erfolgreich. Eigentlich bescheuert.</p>
<p>Nehmen wir einfach mal an dass es nur zwei Arten von <code>T</code> s gibt, für die <code>iterator_traits::value_type</code> gültig ist: Klassen mit einem Member <code>value_type</code> , und Zeiger. Dann funktioniert das folgende:</p>
<pre><code>#include &lt;iostream&gt;

template &lt;int i&gt; struct choice : choice&lt;i+1&gt; {};
template &lt;&gt; struct choice&lt;10&gt; {};

template &lt;typename T&gt;
void f_impl( choice&lt;0&gt;, T, T, typename T::value_type ) {std::cout &lt;&lt; __PRETTY_FUNCTION__ &lt;&lt; '\n';}

template &lt;typename T&gt; struct identity {typedef T type;};

template &lt;typename T&gt;
void f_impl( choice&lt;1&gt;, T*, T*, typename identity&lt;T&gt;::type ) // non-deduced context für Parameter 3
{std::cout &lt;&lt; __PRETTY_FUNCTION__ &lt;&lt; '\n';}

template &lt;typename T, typename U&gt;
void f_impl( choice&lt;2&gt;, T, T, U ) {std::cout &lt;&lt; __PRETTY_FUNCTION__ &lt;&lt; '\n';}

template &lt;typename T, typename U&gt;
void f(T a, T b, U u)
{
	f_impl(choice&lt;0&gt;(), a, b, u);
}

int main()
{
	int const*a;
	f(a,a, 7);
	f(a,a, &quot;aewf&quot;);

	std::string str;
	f(str.end(), str.end(), '7');
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2422008</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2422008</guid><dc:creator><![CDATA[Columbo]]></dc:creator><pubDate>Mon, 13 Oct 2014 15:03:10 GMT</pubDate></item><item><title><![CDATA[Reply to sfinae und iterator_traits on Mon, 13 Oct 2014 16:02:40 GMT]]></title><description><![CDATA[<p>Arcoth schrieb:</p>
<blockquote>
<p>hast du das etwa abgeschrieben?</p>
</blockquote>
<p>rhetorische Frage, oder?</p>
<p>Arcoth schrieb:</p>
<blockquote>
<p>Denn es ist die falsche Erklärung, schließlich existiert die Regel genau so in C++11 und mit -std=c++11 funktioniert es plötzlich, sowohl mit Clang als auch GCC.</p>
</blockquote>
<p>Da dein clang vermutlich die Header von gcc verwendet, geht es nur um einen Compiler. Seit Version 4.6 macht gcc etwas Seltsames: das allgemeine iterator_traits&lt;T&gt; ist dort leer für T, die keinen Typ T::iterator_category haben (und gleichzeitig c++0x/c++11 aktiv ist). Soweit erkennbar, widerspricht das dem Wortlaut des Standards. Kurze Suche im gcc-Bugtracker hat nichts gefunden und ich habe keine Lust, die commits durchzusehen.</p>
<p>Das Problem lässt sich reduzieren auf</p>
<pre><code class="language-cpp">template &lt;typename T&gt; struct foo { typedef typename T::type type; };
int main() { sizeof(foo&lt;int&gt;); } // ill-formed
</code></pre>
<p>und ist weder in C++03 noch C++11 zulässig.</p>
<p>/usr/lib/gcc/x86_64-pc-linux-gnu/4.9.1/include/g++-v4/bits/stl_iterator_base_types.h</p>
<pre><code>#if __cplusplus &gt;= 201103L

_GLIBCXX_HAS_NESTED_TYPE(iterator_category)

  template&lt;typename _Iterator,
           bool = __has_iterator_category&lt;_Iterator&gt;::value&gt;
    struct __iterator_traits { };

  template&lt;typename _Iterator&gt;
    struct __iterator_traits&lt;_Iterator, true&gt;
    {
      typedef typename _Iterator::iterator_category iterator_category;
      typedef typename _Iterator::value_type        value_type;
      typedef typename _Iterator::difference_type   difference_type;
      typedef typename _Iterator::pointer           pointer;
      typedef typename _Iterator::reference         reference;
    };

  template&lt;typename _Iterator&gt;
    struct iterator_traits
    : public __iterator_traits&lt;_Iterator&gt; { };
#else
  template&lt;typename _Iterator&gt;
    struct iterator_traits
    {
      typedef typename _Iterator::iterator_category iterator_category;
      typedef typename _Iterator::value_type        value_type;
      typedef typename _Iterator::difference_type   difference_type;
      typedef typename _Iterator::pointer           pointer;
      typedef typename _Iterator::reference         reference;
    };
#endif
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2422019</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2422019</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Mon, 13 Oct 2014 16:02:40 GMT</pubDate></item><item><title><![CDATA[Reply to sfinae und iterator_traits on Mon, 13 Oct 2014 16:25:05 GMT]]></title><description><![CDATA[<p>statt iterator_traits könnte man hier evtl. auch einfach direkt einen passenden Ausdruck verwenden, ungefähr so:</p>
<pre><code class="language-cpp">template &lt;bool b, typename T = void&gt; struct enable_if { typedef T type; };
template &lt;typename T&gt; struct enable_if&lt;false, T&gt; {};
template &lt;typename T&gt; T declval();

template&lt;typename T, typename U&gt;
void f_(T, T, U, ...)
{
}
template&lt;typename T, typename U&gt;
typename enable_if&lt;sizeof((*declval&lt;T&gt;())=declval&lt;U&gt;())!=0&gt;::type f_(T, T, U, int)
{
}

template&lt;typename T, typename U&gt;
void f(T a, T b, U c)
{
    f_(a,b,c,0);
}
</code></pre>
<p>vorausgesetzt, value_type verhält sich einigermaßen normal (u.a. kein void-return bei Zuweisung).</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2422022</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2422022</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Mon, 13 Oct 2014 16:25:05 GMT</pubDate></item><item><title><![CDATA[Reply to sfinae und iterator_traits on Mon, 13 Oct 2014 17:10:57 GMT]]></title><description><![CDATA[<blockquote>
<p>Da dein clang vermutlich die Header von gcc verwendet</p>
</blockquote>
<p><img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f615.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--confused_face"
      title=":confused:"
      alt="😕"
    /> Hast du überhaupt mal libc++' Implementierung getestet? Mit der kompiliert der im OP gezeigte Code einwandfrei. Zumindest auf meiner Maschine mit libc++ 3.5. Dass gleich beide Implementierungen nicht standardkonform sind konnte ich gar nicht glauben und mir alle Defekt-Reports zum Thema deduction failures angeschaut. Nächstes mal zweifle ich zuerst an der Implementierung als an meinem Verständnis des Standards.</p>
<blockquote>
<p>vorausgesetzt, value_type verhält sich einigermaßen normal (u.a. kein void-return bei Zuweisung).</p>
</blockquote>
<p><code>sizeof(..., 0)</code> ?</p>
<blockquote>
<p>template &lt;typename T&gt; T declval();</p>
</blockquote>
<p>Offenbar die falsche Deklaration. Nicht jeder Zuweisungsoperator kann rvalues nehmen.<br />
Edit: Oder doch?</p>
<p>P.S.: Wieso sollte dein Code für ältere Compiler eigentlich funktionieren? Können die expression SFINAE? Laut dem Paper für C++11 können ältere (das heißt, die hier relevanten) das nämlich nicht. Du hast sicherlich GCC 4.0 installiert, wie sieht's damit aus?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2422024</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2422024</guid><dc:creator><![CDATA[Columbo]]></dc:creator><pubDate>Mon, 13 Oct 2014 17:10:57 GMT</pubDate></item><item><title><![CDATA[Reply to sfinae und iterator_traits on Mon, 13 Oct 2014 18:06:32 GMT]]></title><description><![CDATA[<p>Arcoth schrieb:</p>
<blockquote>
<p><img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f615.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--confused_face"
      title=":confused:"
      alt="😕"
    /> Hast du überhaupt mal libc++' Implementierung getestet? Mit der kompiliert der im OP gezeigte Code einwandfrei. Zumindest auf meiner Maschine mit libc++ 3.5. Dass gleich beide Implementierungen nicht standardkonform sind konnte ich gar nicht glauben und mir alle Defekt-Reports zum Thema deduction failures angeschaut. Nächstes mal zweifle ich zuerst an der Implementierung als an meinem Verständnis des Standards.</p>
</blockquote>
<p>das erfreut mich dass der code doch korrekt wäre (das ist doch die implikation oder?).</p>
<p>Arcoth schrieb:</p>
<blockquote>
<p><code>sizeof(..., 0)</code> ?</p>
</blockquote>
<p>hier hast du vermutlich eher ,1 gemeint (ansonsten muss man auch die ungleichung dahinter ändern).</p>
<p>Arcoth schrieb:</p>
<blockquote>
<p>Offenbar die falsche Deklaration. Nicht jeder Zuweisungsoperator kann rvalues nehmen.<br />
Edit: Oder doch?</p>
</blockquote>
<p>seh ich auch so. die korrekte deklaration von declval ist mit unqualifizierter lvalue-referenz.</p>
<p>Arcoth schrieb:</p>
<blockquote>
<p>P.S.: Wieso sollte dein Code für ältere Compiler eigentlich funktionieren? Können die expression SFINAE? Laut dem Paper für C++11 können ältere (das heißt, die hier relevanten) das nämlich nicht. Du hast sicherlich GCC 4.0 installiert, wie sieht's damit aus?</p>
</blockquote>
<p>so aus neugier und unwissenheit: wäre expression sfinae nach c++03 korrekt? ab und zu hat expression-sfinae bei mir sichtbarkeit von membern / methoden ignoriert. <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f615.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--confused_face"
      title=":/"
      alt="😕"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/2422034</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2422034</guid><dc:creator><![CDATA[hanstroll123]]></dc:creator><pubDate>Mon, 13 Oct 2014 18:06:32 GMT</pubDate></item><item><title><![CDATA[Reply to sfinae und iterator_traits on Mon, 13 Oct 2014 18:39:08 GMT]]></title><description><![CDATA[<blockquote>
<p>das erfreut mich dass der code doch korrekt wäre (das ist doch die implikation oder?).</p>
</blockquote>
<p>Ich fürchte nicht. Die Implikation ist dass die falschen Implementierungen von sowohl Clang als auch GCC mit dem Code momentan funktionieren. campers Lösung ist wahrscheinlich die die deinem Problem am nahsten kommt.</p>
<blockquote>
<p>hier hast du vermutlich eher ,1 gemeint (ansonsten muss man auch die ungleichung dahinter ändern).</p>
</blockquote>
<p><code>sizeof</code> nimmt die Größe des Ausdrucktyps, welchen Wert dieser hat ist völlig egal.</p>
<blockquote>
<p>so aus neugier und unwissenheit: wäre expression sfinae nach c++03 korrekt?</p>
</blockquote>
<p>Ja. Es gab aber lange Zeit Zweifel ob das der Fall ist oder nicht, und auch aus dem Grund haben einige Compiler das nicht implementiert. <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2634.html" rel="nofollow">N2634</a> erklärt das.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2422038</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2422038</guid><dc:creator><![CDATA[Columbo]]></dc:creator><pubDate>Mon, 13 Oct 2014 18:39:08 GMT</pubDate></item><item><title><![CDATA[Reply to sfinae und iterator_traits on Mon, 13 Oct 2014 19:21:30 GMT]]></title><description><![CDATA[<p>Arcoth schrieb:</p>
<blockquote>
<blockquote>
<p>Da dein clang vermutlich die Header von gcc verwendet</p>
</blockquote>
<p><img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f615.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--confused_face"
      title=":confused:"
      alt="😕"
    /> Hast du überhaupt mal libc++' Implementierung getestet? Mit der kompiliert der im OP gezeigte Code einwandfrei. Zumindest auf meiner Maschine mit libc++ 3.5. Dass gleich beide Implementierungen nicht standardkonform sind konnte ich gar nicht glauben und mir alle Defekt-Reports zum Thema deduction failures angeschaut. Nächstes mal zweifle ich zuerst an der Implementierung als an meinem Verständnis des Standards.</p>
</blockquote>
<p>nicht mit libc++ getestet, da nicht installiert. Ist ja kein integraler Bestandteil des Compilers.</p>
<p>Arcoth schrieb:</p>
<blockquote>
<blockquote>
<p>vorausgesetzt, value_type verhält sich einigermaßen normal (u.a. kein void-return bei Zuweisung).</p>
</blockquote>
<p><code>sizeof(..., 0)</code> ?</p>
</blockquote>
<p>gute Idee.</p>
<p>Arcoth schrieb:</p>
<blockquote>
<blockquote>
<p>template &lt;typename T&gt; T declval();</p>
</blockquote>
<p>Offenbar die falsche Deklaration. Nicht jeder Zuweisungsoperator kann rvalues nehmen.</p>
</blockquote>
<p>Zutreffend, allerdings ist der Typ dann in C++03 vermutlich nicht mehr Containerkompatibel. Es ging mir hier nur um eine Prototypen. ggf. muss man eben auf declval&lt;T&amp;&gt;() zurückgreifen.</p>
<p>Arcoth schrieb:</p>
<blockquote>
<p>P.S.: Wieso sollte dein Code für ältere Compiler eigentlich funktionieren? Können die expression SFINAE? Laut dem Paper für C++11 können ältere (das heißt, die hier relevanten) das nämlich nicht. Du hast sicherlich GCC 4.0 installiert, wie sieht's damit aus?</p>
</blockquote>
<p>mit</p>
<pre><code class="language-cpp">int main()
{
    int* p = 0;
    void* q = 0;
    f(p,p,0);
    f(q,q,0);
}
</code></pre>
<p>3.4.6 - ICE<br />
4.0.4 - 4.3.6: error: ‘void*’ is not a pointer-to-object type<br />
4.4.7 - 4.6.4: sorry, unimplemented: mangling modop_expr<br />
ab 4.7. geht es dann...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2422043</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2422043</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Mon, 13 Oct 2014 19:21:30 GMT</pubDate></item><item><title><![CDATA[Reply to sfinae und iterator_traits on Mon, 13 Oct 2014 19:57:37 GMT]]></title><description><![CDATA[<p><a href="https://gcc.gnu.org/bugzilla/show_bug.cgi?id=45549" rel="nofollow">Hier</a> ist der gcc-Bug, der zu der Änderung in der Standardbibliothek geführt hat. Falls sich libc++ hier genauso verhält, dann vermutlich aus den gleichen Gründen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2422049</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2422049</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Mon, 13 Oct 2014 19:57:37 GMT</pubDate></item><item><title><![CDATA[Reply to sfinae und iterator_traits on Mon, 13 Oct 2014 23:21:15 GMT]]></title><description><![CDATA[<p>Was genau kann GCC 4.4.7 nicht mangeln? Anscheinend die Zuweisung:</p>
<p>&lt;a href= schrieb:</p>
<blockquote>
<p>Mark Mitchell&quot;&gt;It's an assignment operator (including compound assignments) while parsing a template.</p>
</blockquote>
<p>camper schrieb:</p>
<blockquote>
<p>nicht mit libc++ getestet, da nicht installiert.</p>
</blockquote>
<p>Wie lange dauert es libc++ auf Gentoo zu installieren? Eine Minute? Ein Vorteil wäre eine breitere Analyse gängiger Implementierungen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2422062</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2422062</guid><dc:creator><![CDATA[Columbo]]></dc:creator><pubDate>Mon, 13 Oct 2014 23:21:15 GMT</pubDate></item><item><title><![CDATA[Reply to sfinae und iterator_traits on Tue, 14 Oct 2014 00:03:12 GMT]]></title><description><![CDATA[<p>Anscheinend war name mangling das einzige Problem für GCC &gt;= 4.4.7.</p>
<pre><code>template &lt;int&gt; struct void_t {typedef void type;};
template &lt;typename T&gt; T declval();

#include &lt;iostream&gt;

template &lt;typename T, typename U, typename=void &gt;
struct check { void operator()(T,T,U){std::cout &lt;&lt; '0';} };

template &lt;typename T, typename U&gt;
struct check&lt;T, U, typename void_t&lt;sizeof((*declval&lt;T&gt;())=declval&lt;U&gt;(),0)&gt;::type&gt; { void operator()(T,T,U){std::cout &lt;&lt; '1';} };;

template&lt;typename T, typename U&gt;
void f(T a, T b, U c)
{
	check&lt;T, U&gt;()(a,b,c);
}

int main()
{
	int* p = 0;
	void* q = 0;
	f(p,p,0);
	f(q,q,0);
}
</code></pre>
<p>(Auf GCC Godbolt getestet; Zwar keine Ausgabe direkt verfügbar, der Assemblercode ist aber aussagekräftig</p>
<pre><code>movb	$49, 15(%rsp)
	movq	%rbx, %rsi
	call	std::basic_ostream&lt;char, std::char_traits&lt;char&gt; &gt;&amp; std::__ostream_insert&lt;char, std::char_traits&lt;char&gt; &gt;(std::basic_ostream&lt;char, std::char_traits&lt;char&gt; &gt;&amp;, char const*, long)
	movq	%rbx, %rsi
	movl	$1, %edx
	movl	std::cout, %edi
	movb	$48, 15(%rsp)
	call	std::basic_ostream&lt;char, std::char_traits&lt;char&gt; &gt;&amp; std::__ostream_insert&lt;char, std::char_traits&lt;char&gt; &gt;(std::basic_ostream&lt;char, std::char_traits&lt;char&gt; &gt;&amp;, char const*, long)
	xorl	%eax, %eax
	addq	$16, %rsp
	popq	%rbx
</code></pre>
<p>)</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2422066</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2422066</guid><dc:creator><![CDATA[Columbo]]></dc:creator><pubDate>Tue, 14 Oct 2014 00:03:12 GMT</pubDate></item><item><title><![CDATA[Reply to sfinae und iterator_traits on Tue, 14 Oct 2014 12:35:23 GMT]]></title><description><![CDATA[<p>Arcoth schrieb:</p>
<blockquote>
<pre><code>template &lt;typename T, typename U&gt;
struct check&lt;T, U, typename void_t&lt;sizeof((*declval&lt;T&gt;())=declval&lt;U&gt;(),0)&gt;::type&gt; { void operator()(T,T,U){std::cout &lt;&lt; '1';} };
</code></pre>
</blockquote>
<p>Interessante Idee. Funktioniert ab g++ 4.4 und 3.4.6. steigt zumindest nicht mehr mit einem ice aus.</p>
<p>Nachdem ich das überschlafen habe, bin ich jetzt der Ansicht, dass das Verhalten von gcc und clang vom Standard gedeckt ist:<br />
Die Instantiierung von iterator_traits für Typen, die die entsprechenden typedefs nicht haben und für die iterator_traits nicht spezialisiert wurde, macht das jeweilige Programm formal ill-formed.<br />
24.4.1/2 ist damit implizit auch eine Spezifikation der Anforderungen, die an das Templateargument gestellt werden, und wenn diese nicht erfüllt werden, greift 17.6.4.8/1, also UB.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2422139</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2422139</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Tue, 14 Oct 2014 12:35:23 GMT</pubDate></item></channel></rss>