<?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[remove_const für Template mit Spezialisierung]]></title><description><![CDATA[<p>Hi,</p>
<pre><code class="language-cpp">#include &lt;type_traits&gt;
#include &lt;iostream&gt;

template&lt;typename T, typename Enable = void&gt; 
class Y
{
public:
    int get() const {return 1;}
};

template&lt;typename T&gt; class O {};

template&lt;template&lt;class&gt; class T, typename TA&gt;
class Y&lt;T&lt;TA&gt;, typename std::enable_if&lt;std::is_same&lt;typename std::remove_cv&lt;T&lt;TA&gt;&gt;::type,
    O&lt;float&gt;&gt;::value&gt;::type&gt;
{
public:
    int get() const {return 2;}
};

int main()
{
    std::cout &lt;&lt; Y&lt;O&lt;float&gt;&gt;().get() &lt;&lt; ' ' &lt;&lt; Y&lt;const O&lt;float&gt;&gt;().get();

    std::cout &lt;&lt; &quot;\nTest: &quot; &lt;&lt; std::is_same&lt;typename std::remove_cv&lt;const O&lt;float&gt;&gt;::type, O&lt;float&gt;&gt;::value;
}
</code></pre>
<p>Wieso ist die Ausgabe hier &quot;2 1\nTest: 1&quot; und nicht &quot;2 2\nTest: 1&quot;?</p>
<p>Zur Erläuterung:<br />
Ich möchte, dass die Spezialisierung für alle <code>O&lt;float&gt;</code> unabhängig der Qualifizierer für <code>O&lt;float&gt;</code> greift. Zeile 25 des Codes liefert ja wie gewünscht true, nur die Spezialisierung greift hier nicht. <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f61e.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--disappointed_face"
      title=":("
      alt="😞"
    /> Woran liegt das?</p>
<p>Danke und viele Grüße!</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/319796/remove_const-für-template-mit-spezialisierung</link><generator>RSS for Node</generator><lastBuildDate>Fri, 24 Jul 2026 17:24:11 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/319796.rss" rel="self" type="application/rss+xml"/><pubDate>Tue, 03 Sep 2013 16:07:11 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to remove_const für Template mit Spezialisierung on Tue, 03 Sep 2013 16:07:11 GMT]]></title><description><![CDATA[<p>Hi,</p>
<pre><code class="language-cpp">#include &lt;type_traits&gt;
#include &lt;iostream&gt;

template&lt;typename T, typename Enable = void&gt; 
class Y
{
public:
    int get() const {return 1;}
};

template&lt;typename T&gt; class O {};

template&lt;template&lt;class&gt; class T, typename TA&gt;
class Y&lt;T&lt;TA&gt;, typename std::enable_if&lt;std::is_same&lt;typename std::remove_cv&lt;T&lt;TA&gt;&gt;::type,
    O&lt;float&gt;&gt;::value&gt;::type&gt;
{
public:
    int get() const {return 2;}
};

int main()
{
    std::cout &lt;&lt; Y&lt;O&lt;float&gt;&gt;().get() &lt;&lt; ' ' &lt;&lt; Y&lt;const O&lt;float&gt;&gt;().get();

    std::cout &lt;&lt; &quot;\nTest: &quot; &lt;&lt; std::is_same&lt;typename std::remove_cv&lt;const O&lt;float&gt;&gt;::type, O&lt;float&gt;&gt;::value;
}
</code></pre>
<p>Wieso ist die Ausgabe hier &quot;2 1\nTest: 1&quot; und nicht &quot;2 2\nTest: 1&quot;?</p>
<p>Zur Erläuterung:<br />
Ich möchte, dass die Spezialisierung für alle <code>O&lt;float&gt;</code> unabhängig der Qualifizierer für <code>O&lt;float&gt;</code> greift. Zeile 25 des Codes liefert ja wie gewünscht true, nur die Spezialisierung greift hier nicht. <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f61e.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--disappointed_face"
      title=":("
      alt="😞"
    /> Woran liegt das?</p>
<p>Danke und viele Grüße!</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2350083</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2350083</guid><dc:creator><![CDATA[Eisflamme]]></dc:creator><pubDate>Tue, 03 Sep 2013 16:07:11 GMT</pubDate></item><item><title><![CDATA[Reply to remove_const für Template mit Spezialisierung on Tue, 03 Sep 2013 16:13:04 GMT]]></title><description><![CDATA[<p>Weil</p>
<pre><code class="language-cpp">T&lt;TA&gt;
</code></pre>
<p>ungleich</p>
<pre><code class="language-cpp">const T&lt;TA&gt;
</code></pre>
<p>.</p>
<p>Generell sieht es nach einer falschen Anwendung von <code>template&lt;class&gt;</code> aus.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2350084</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2350084</guid><dc:creator><![CDATA[kurze antwort]]></dc:creator><pubDate>Tue, 03 Sep 2013 16:13:04 GMT</pubDate></item><item><title><![CDATA[Reply to remove_const für Template mit Spezialisierung on Tue, 03 Sep 2013 16:16:04 GMT]]></title><description><![CDATA[<p>Dafür ja mein Test, der aber true ergibt...</p>
<p>Und die Spezialisierung greift für Templateklassen an sich doch, wie man an der ersten 2 sieht. Hast Du solange gelesen und nachgedacht wie Deine Antwort ist oder steckt da doch mehr Weisheit hinter als ich erkennen kann? <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f60b.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--face_savoring_food"
      title=":yum:"
      alt="😋"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/2350085</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2350085</guid><dc:creator><![CDATA[Eisflamme]]></dc:creator><pubDate>Tue, 03 Sep 2013 16:16:04 GMT</pubDate></item><item><title><![CDATA[Reply to remove_const für Template mit Spezialisierung on Tue, 03 Sep 2013 16:17:46 GMT]]></title><description><![CDATA[<p>Die Weisheit ist, dass, wenn du Zeile 14 in</p>
<pre><code class="language-cpp">class Y&lt;const T&lt;TA&gt;, ...
</code></pre>
<p>änderst, die Ausgabe 1 2 ist und nicht mehr 2 1.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2350086</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2350086</guid><dc:creator><![CDATA[kurze antwort]]></dc:creator><pubDate>Tue, 03 Sep 2013 16:17:46 GMT</pubDate></item><item><title><![CDATA[Reply to remove_const für Template mit Spezialisierung on Tue, 03 Sep 2013 16:21:46 GMT]]></title><description><![CDATA[<p>Stimmt, Tim. Und wie löse ich mein Problem? <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f61e.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--disappointed_face"
      title=":("
      alt="😞"
    /></p>
<p>Edit: template&lt;class&gt; brauche ich, weil ich (1) qualifizierunabhängige Templates aber auch (2) qualifiziererunabhängige Templateargumente (in Kombination mit (1)) haben möchte.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2350089</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2350089</guid><dc:creator><![CDATA[Eisflamme]]></dc:creator><pubDate>Tue, 03 Sep 2013 16:21:46 GMT</pubDate></item><item><title><![CDATA[Reply to remove_const für Template mit Spezialisierung on Tue, 03 Sep 2013 16:27:58 GMT]]></title><description><![CDATA[<p>Kurzer Fix:</p>
<pre><code class="language-cpp">template&lt;typename T&gt; class O {
public:
  typedef T type;
};

template&lt;typename T&gt;
class Y&lt;T,
        typename std::enable_if&lt;std::is_same&lt;typename std::remove_cv&lt;T&gt;::type,
                                             O&lt;float&gt;&gt;::value&gt;::type&gt;
{
  typedef typename T::type TA;
 public:
  int get() const {return 2;}
};
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2350090</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2350090</guid><dc:creator><![CDATA[kurze antwort]]></dc:creator><pubDate>Tue, 03 Sep 2013 16:27:58 GMT</pubDate></item><item><title><![CDATA[Reply to remove_const für Template mit Spezialisierung on Tue, 03 Sep 2013 16:30:07 GMT]]></title><description><![CDATA[<p>Okay, dankeschön!</p>
<p>Und wie erweitere ich das dazu, dass der Template-Parametertyp inkl. seiner Qualifizierer egal ist? Denn das war mein eigentliches Ziel und darum bin ich überhaupt erst über die template&lt;class&gt;class-Schiene gegangen</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2350091</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2350091</guid><dc:creator><![CDATA[Eisflamme]]></dc:creator><pubDate>Tue, 03 Sep 2013 16:30:07 GMT</pubDate></item><item><title><![CDATA[Reply to remove_const für Template mit Spezialisierung on Tue, 03 Sep 2013 17:59:50 GMT]]></title><description><![CDATA[<pre><code class="language-cpp">template &lt;typename T&gt;
struct identity { using type = T; };
template &lt;typename T&gt;
using eval = typename T::type;

template&lt;typename T, typename Enable = void&gt;
class Y
{
public:
    int get() const {return 1;}
};

template&lt;typename T&gt; class O {};

template &lt;typename T&gt; struct A;
template &lt;template &lt;typename&gt; class T, typename TA&gt; struct A&lt;T&lt;TA&gt;&gt;
    : identity&lt;T&lt;eval&lt;std::remove_cv&lt;TA&gt;&gt;&gt;&gt; {};

template&lt;class T&gt;
class Y&lt;T, eval&lt;std::enable_if&lt;std::is_same&lt;eval&lt;A&lt;eval&lt;std::remove_cv&lt;T&gt;&gt;&gt;&gt;, O&lt;float&gt;&gt;::value&gt;&gt;&gt;
{
public:
    int get() const {return 2;}
};
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2350101</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2350101</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Tue, 03 Sep 2013 17:59:50 GMT</pubDate></item><item><title><![CDATA[Reply to remove_const für Template mit Spezialisierung on Tue, 03 Sep 2013 18:25:29 GMT]]></title><description><![CDATA[<p>Wow, danke!</p>
<p>Leider habe ich immer noch kein C++11-using zur Verfügung, was Zeilen 3-4 für mich nicht möglich machen, typedef kann ja sowas nicht, richtig? Funktioniert es auch ohne? <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="🙂"
    /></p>
<p>Achso, vermutlich einfach mit:</p>
<pre><code class="language-cpp">template&lt;typename T, typename U&gt;
struct eval
{
    typedef typename T::U type;
};
</code></pre>
<p>nebst Ersetzen von eval&lt;.&gt; durch eval&lt;.&gt;::type, richtig?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2350105</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2350105</guid><dc:creator><![CDATA[Eisflamme]]></dc:creator><pubDate>Tue, 03 Sep 2013 18:25:29 GMT</pubDate></item><item><title><![CDATA[Reply to remove_const für Template mit Spezialisierung on Tue, 03 Sep 2013 18:24:58 GMT]]></title><description><![CDATA[<p>Eisflamme schrieb:</p>
<blockquote>
<p>Wow, danke!</p>
<p>Leider habe ich immer noch kein C++11-using zur Verfügung, was Zeilen 3-4 für mich nicht möglich machen, typedef kann ja sowas nicht, richtig? Funktioniert es auch ohne? <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="🙂"
    /></p>
</blockquote>
<p>Ja, structe da mal drumrum <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>
]]></description><link>https://www.c-plusplus.net/forum/post/2350106</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2350106</guid><dc:creator><![CDATA[[[global:guest]]]]></dc:creator><pubDate>Tue, 03 Sep 2013 18:24:58 GMT</pubDate></item><item><title><![CDATA[Reply to remove_const für Template mit Spezialisierung on Tue, 03 Sep 2013 18:28:31 GMT]]></title><description><![CDATA[<p>Dann wird es bloss ein bisschen länger. z.B.</p>
<pre><code class="language-cpp">#include &lt;type_traits&gt;
#include &lt;iostream&gt;

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

template&lt;typename T, typename Enable = void&gt;
class Y
{
public:
    int get() const {return 1;}
};

template&lt;typename T&gt; class O {};

template &lt;typename T&gt; struct Analyze;
template &lt;template &lt;typename&gt; class T, typename TA&gt; struct Analyze&lt;T&lt;TA&gt;&gt;
{
    typedef TA type;
    template &lt;typename X&gt;
    struct apply
        : identity&lt;T&lt;X&gt;&gt; {};
};

template&lt;class T&gt;
class Y&lt;T, typename std::enable_if&lt;std::is_same&lt;
    typename Analyze&lt;typename std::remove_cv&lt;T&gt;::type&gt;::template apply&lt;
        typename std::remove_cv&lt;typename Analyze&lt;typename std::remove_cv&lt;T&gt;::type&gt;::type&gt;::type&gt;::type,
    O&lt;float&gt;&gt;::value&gt;::type&gt;
{
public:
    int get() const {return 2;}
};
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2350108</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2350108</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Tue, 03 Sep 2013 18:28:31 GMT</pubDate></item><item><title><![CDATA[Reply to remove_const für Template mit Spezialisierung on Tue, 03 Sep 2013 18:35:42 GMT]]></title><description><![CDATA[<p>Eisflamme schrieb:</p>
<blockquote>
<p>Achso, vermutlich einfach mit:</p>
<pre><code class="language-cpp">template&lt;typename T, typename U&gt;
struct eval
{
    typedef typename T::U type;
};
</code></pre>
<p>nebst Ersetzen von eval&lt;.&gt; durch eval&lt;.&gt;::type, richtig?</p>
</blockquote>
<p>Das ist hoffentlich ein Scherz.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2350110</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2350110</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Tue, 03 Sep 2013 18:35:42 GMT</pubDate></item><item><title><![CDATA[Reply to remove_const für Template mit Spezialisierung on Tue, 03 Sep 2013 19:08:16 GMT]]></title><description><![CDATA[<p>Oh na ja, habe mich verlesen. Aber mir fehlt jetzt zu viel Verständnis, denn meine andere Lösung wäre auch nur mit ::U durch ::type ersetzt gewesen.</p>
<p>Danke für den Code jedenfalls! Nutzt Du irgendwelche googlebaren Konzepte dafür, die ich vermutlich nicht kenne? (also SFNIAE ist mir prinzipiell erstmal bekannt, viel weiter komme ich wohl aber auch nicht <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f644.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--face_with_rolling_eyes"
      title=":rolling_eyes:"
      alt="🙄"
    />) Erstmal verstehe ich ihn leider nicht, aber ich kann jetzt auch keine Erklärung von Grundkonzepten erwarten.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2350112</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2350112</guid><dc:creator><![CDATA[Eisflamme]]></dc:creator><pubDate>Tue, 03 Sep 2013 19:08:16 GMT</pubDate></item><item><title><![CDATA[Reply to remove_const für Template mit Spezialisierung on Tue, 03 Sep 2013 19:36:47 GMT]]></title><description><![CDATA[<p>Eigentlich ist die Lösung recht einfach, nur durch die umständliche Syntax sieht das komplizierter aus als es ist.</p>
<p>Ein T&lt;TA&gt; (T ein Klassenmtemlate) produziert immer einen unqualifizierten Typen. Also muss Y erst einmal einen einfachen Typparameter haben, um sowohl const-qualifizierte als auch u-unqualifizierte Argumente anzunehmen (wenn man nicht 4 Versionen für alle cv-Varianten schreiben will).<br />
Dann muss die notwendige Zerlegung in Klassentemplate und Templateargument folglich an ein anderes Template delegiert werden, hier: Analyze. Diesem Template übergeben wir ein unqualifiziertes Argument, so dass die Zerlegung unproblematisch ist. Analyze hat dann entsprechende Member, um auf die Zerlegung zugreifen zu könne. apply fungiert dabei als Pseude-Template-typedef, analog zu ::other in Allokatoren (mit using-Unterstützung würde man ein Aliastemplate verwenden).</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2350122</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2350122</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Tue, 03 Sep 2013 19:36:47 GMT</pubDate></item><item><title><![CDATA[Reply to remove_const für Template mit Spezialisierung on Wed, 04 Sep 2013 07:47:50 GMT]]></title><link>https://www.c-plusplus.net/forum/post/2350156</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2350156</guid><dc:creator><![CDATA[Sone]]></dc:creator><pubDate>Wed, 04 Sep 2013 07:47:50 GMT</pubDate></item><item><title><![CDATA[Reply to remove_const für Template mit Spezialisierung on Wed, 04 Sep 2013 15:22:08 GMT]]></title><description><![CDATA[<p>Hi,</p>
<p>okay, super. Habe es mehrfach gelesen und jetzt verstanden. <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="🙂"
    /></p>
<p>Ich fand heraus, dass ich eigentlich etwas haben möchte wie <code>is_same_template</code> , was herausfindet ob für einen übergebenen Typ T das Template U verwendet wurde. Wobei bei einem übergebenem Typen <code>const T&lt;...&gt;</code> trotzdem ein match auf U (Template, non-const) passen soll.</p>
<p>Und das will ich jetzt Mal auslagern, damit man es nicht jedes Mal neu schreiben muss. Jetzt habe ich aber ein Problem:</p>
<pre><code class="language-cpp">#include &lt;type_traits&gt; 
#include &lt;iostream&gt; 

// Die Templates

template&lt;typename T&gt; struct analyzer
{
	static const bool is_template = false; // mein kläglicher Versuch ihn davon abzuhalten den rechten Ausdruck von is_same_template::value auszuwerten
};

template&lt;template&lt;typename&gt; class T, typename TA&gt;
struct analyzer&lt;T&lt;TA&gt;&gt;
{
	static const bool is_template = true;

	typedef TA ptype;

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

template&lt;typename T, template &lt;typename&gt; class U, typename Enable = void&gt;
struct is_same_template;

template&lt;typename T, template &lt;typename&gt; class U&gt;
struct is_same_template&lt;T, U, typename std::enable_if&lt;std::is_class&lt;T&gt;::value&gt;::type&gt;
{
	typedef analyzer&lt;typename std::remove_cv&lt;T&gt;::type&gt; analyzerT;

	static const bool value = analyzerT::is_template &amp;&amp; std::is_same
	&lt;
		typename analyzerT::template apply&lt;typename std::remove_cv&lt;typename analyzerT::ptype&gt;::type&gt;::type,
		U&lt;typename std::remove_cv&lt;typename analyzerT::ptype&gt;::type&gt;
	&gt;::value;
};

// Die Nutzung

template&lt;typename T&gt; class O {};

template&lt;typename T, typename Enable = void&gt; 
class Y 
{ 
public: 
    int get() const {return 1;} 
}; 

template&lt;typename T&gt;
class Y&lt;T, typename std::enable_if&lt;is_same_template&lt;T, O&gt;::value&gt;::type&gt;
{
public:
	int get() const {return 4;}
};

int main()
{
	struct NoTemplate {};

	Y&lt;NoTemplate&gt; aMinus1;
	Y&lt;int&gt; a0;
	Y&lt;O&lt;int&gt;&gt; a1;
	Y&lt;O&lt;float&gt;&gt; a2;
	Y&lt;const O&lt;float&gt;&gt; a3;
	Y&lt;O&lt;const int&gt;&gt; a4;
	Y&lt;const O&lt;const float&gt;&gt; a5;
	const Y&lt;const O&lt;const int&gt;&gt; a6;

	std::cout &lt;&lt; aMinus1.get() &lt;&lt; '\n' &lt;&lt; a0.get() &lt;&lt; '\n' &lt;&lt; a1.get() &lt;&lt; '\n' &lt;&lt; a2.get() &lt;&lt; '\n' &lt;&lt; a3.get() &lt;&lt; '\n' &lt;&lt; a4.get() &lt;&lt; '\n' &lt;&lt; a5.get() &lt;&lt; '\n' &lt;&lt; a6.get() &lt;&lt; '\n';
}
</code></pre>
<p>aMinus1 kompiliert nicht. Zwar stellt er über <code>is_template</code> fest, dass es kein Template ist, jedoch wertet er den rechten Ausdruck von <code>is_same_template::value</code> trotzdem noch aus, was dann zum Fehler führt, da er ptype und apply nicht kennt. Soll ich da einfach ein Dummy-Interface nachbauen oder gibt es eine elegantere Lösung?</p>
<p>Edit:<br />
Wieso kompiliert ideone das überhaupt für <code>Y&lt;int&gt; a0;</code> ? Für den Fall greift doch die Spezialisierung nicht, er fällt auf die Basisversion zurück und die hat kein value, ist das kein Compile-Error?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2350303</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2350303</guid><dc:creator><![CDATA[Eisflamme]]></dc:creator><pubDate>Wed, 04 Sep 2013 15:22:08 GMT</pubDate></item><item><title><![CDATA[Reply to remove_const für Template mit Spezialisierung on Wed, 04 Sep 2013 15:32:02 GMT]]></title><description><![CDATA[<pre><code>#include &lt;type_traits&gt;
#include &lt;iostream&gt;

template&lt; typename T,
          template&lt;class&gt; class U &gt;
struct is_specialization_impl : std::false_type {};

template&lt; typename T,
          template&lt;class&gt; class U &gt;
struct is_specialization_impl&lt;U&lt;T&gt;, U&gt; : std::true_type {};

template&lt; typename T,
          template&lt;class&gt; class U &gt;
struct is_specialization : is_specialization_impl&lt; typename std::remove_cv&lt;T&gt;::type, U &gt; {};

/// _________________________________________________________________

template&lt;typename T&gt; class O {};

template&lt;typename T, typename Enable = void&gt;
class Y
{
public:
    static constexpr int get() {return 1;}
};

template&lt;typename T&gt;
class Y&lt;T, typename std::enable_if&lt;is_specialization&lt;T, O&gt;::value&gt;::type&gt;
{
public:
    static constexpr int get() {return 4;}
};

int main()
{
    struct NoTemplate {};

    static_assert( Y&lt;NoTemplate&gt;::get() == 1, &quot;&quot; );
    static_assert( Y&lt;int&gt;::get() == 1, &quot;&quot; );
    static_assert( Y&lt;O&lt;int&gt;&gt;::get() == 4, &quot;&quot; );
    static_assert( Y&lt;O&lt;float&gt;&gt;::get() == 4, &quot;&quot; );
    static_assert( Y&lt;const O&lt;float&gt;&gt;::get() == 4, &quot;&quot; );
    static_assert( Y&lt;const O&lt;const float&gt;&gt;::get() == 4, &quot;&quot; );
}
</code></pre>
<p>?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2350307</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2350307</guid><dc:creator><![CDATA[Sone]]></dc:creator><pubDate>Wed, 04 Sep 2013 15:32:02 GMT</pubDate></item><item><title><![CDATA[Reply to remove_const für Template mit Spezialisierung on Wed, 04 Sep 2013 15:35:58 GMT]]></title><description><![CDATA[<p>Die Frage, ob ein (zumindest potentiell ausgewerteter) Operand tatsächlich ausgewertet wird oder nicht ist nicht relvant dafür, ob dieser ggf. erst instantiiert werden muss. Dein Problem ist ganz klassich analog zu z.B.</p>
<pre><code class="language-cpp">template &lt;int N&gt;
struct fak
{
    static const int value = N != 0 ? N * fak&lt;N-1&gt;::value : 1;
};
</code></pre>
<p>das auch nicht ohne zusätzliche Spezialisierung auskommt.</p>
<pre><code class="language-cpp">std::is_same
    &lt;
        typename analyzerT::template apply&lt;typename std::remove_cv&lt;typename analyzerT::ptype&gt;::type&gt;::type,
        U&lt;typename std::remove_cv&lt;typename analyzerT::ptype&gt;::type&gt;
    &gt;::value;
</code></pre>
<p>das ist komplizierter als es sein muss. Es kommt ja gar nicht darauf an, mit welchen konkreten Templateargument das Template gefüttert wird (und auch nicht, ob die entsprechende Spezialisierung instantiiert werden kann). Ein Test mit irgendeinem Typen, der bequem aufzuschreiben ist, reicht völlig aus (das wäre mit Aliastemplates anders, aber die können sowieso nicht selbst Templateargumente sein).</p>
<pre><code class="language-cpp">std::is_same&lt;typename analyzerT::template apply&lt;int&gt;, U&lt;int&gt;&gt;::value
</code></pre>
<p>Das ist dann wieder kurz genug, dass man es direkt ins enable_if schreiben kann.</p>
<p>Edit: Sones Variante ist nat. schöner.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2350308</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2350308</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Wed, 04 Sep 2013 15:35:58 GMT</pubDate></item><item><title><![CDATA[Reply to remove_const für Template mit Spezialisierung on Wed, 04 Sep 2013 16:03:11 GMT]]></title><description><![CDATA[<p>Sone schrieb:</p>
<blockquote>
<pre><code>int main()
{
    struct NoTemplate {};

    Y&lt;NoTemplate&gt;::get();
}
</code></pre>
</blockquote>
<p><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="😮"
    /> Ist das seit C++11 erlaubt?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2350315</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2350315</guid><dc:creator><![CDATA[[[global:guest]]]]></dc:creator><pubDate>Wed, 04 Sep 2013 16:03:11 GMT</pubDate></item><item><title><![CDATA[Reply to remove_const für Template mit Spezialisierung on Wed, 04 Sep 2013 16:03:56 GMT]]></title><description><![CDATA[<blockquote>
<p>Ist das seit C++11 erlaubt?</p>
</blockquote>
<p>Wieso C++11? Das war schon immer erlaubt...</p>
<blockquote>
<p>Edit: Sones Variante ist nat. schöner.</p>
</blockquote>
<p><a href="http://www.memes.at/faces/epic_win.jpg" rel="nofollow">http://www.memes.at/faces/epic_win.jpg</a></p>
]]></description><link>https://www.c-plusplus.net/forum/post/2350316</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2350316</guid><dc:creator><![CDATA[Sone]]></dc:creator><pubDate>Wed, 04 Sep 2013 16:03:56 GMT</pubDate></item><item><title><![CDATA[Reply to remove_const für Template mit Spezialisierung on Wed, 04 Sep 2013 16:08:47 GMT]]></title><description><![CDATA[<p>27 Sekunden! <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="🙂"
    /></p>
<p>Sone schrieb:</p>
<blockquote>
<blockquote>
<p>Ist das seit C++11 erlaubt?</p>
</blockquote>
<p>Wieso C++11? Das war schon immer erlaubt...</p>
</blockquote>
<p>Nein, das war vor deiner Zeit. In C++03 waren lokale Typen als Templateargumente noch verboten. Soll ich dir die Stelle im Standard raus suchen <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>
]]></description><link>https://www.c-plusplus.net/forum/post/2350317</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2350317</guid><dc:creator><![CDATA[[[global:guest]]]]></dc:creator><pubDate>Wed, 04 Sep 2013 16:08:47 GMT</pubDate></item><item><title><![CDATA[Reply to remove_const für Template mit Spezialisierung on Wed, 04 Sep 2013 17:03:32 GMT]]></title><description><![CDATA[<p>Sone schrieb:</p>
<blockquote>
<p>KasF schrieb:</p>
<blockquote>
<p>Sone schrieb:</p>
<blockquote>
<pre><code>int main()
{
    struct NoTemplate {};

    Y&lt;NoTemplate&gt;::get();
}
</code></pre>
</blockquote>
<p><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="😮"
    /> Ist das seit C++11 erlaubt?</p>
</blockquote>
<p>Wieso C++11? Das war schon immer erlaubt...</p>
</blockquote>
<p>Das stimmt nicht. Funktionslokale Typen durften früher nicht als Template-Argumente verwendet werden.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2350338</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2350338</guid><dc:creator><![CDATA[krümelkacker]]></dc:creator><pubDate>Wed, 04 Sep 2013 17:03:32 GMT</pubDate></item><item><title><![CDATA[Reply to remove_const für Template mit Spezialisierung on Wed, 04 Sep 2013 17:48:09 GMT]]></title><description><![CDATA[<p>Merkwürdig. Wo genau ist denn der konzeptuelle Unterschied von einer funktionslokalen Klasse zu einer Klasse, die nach dem Template deklariert(-finiert) wurde? Wieso hat C++03 da eine solches Verbot ausgehängt* <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="😕"
    /></p>
<p>Aber du hast vollkommen Recht, das war vor dieser Ära in der ich &quot;aufgewachsen&quot; bin.</p>
<p>~* Ich habe das Gefühl, Herb Sutter hat bestimmt etwas dazu geschrieben.~</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2350352</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2350352</guid><dc:creator><![CDATA[Sone]]></dc:creator><pubDate>Wed, 04 Sep 2013 17:48:09 GMT</pubDate></item><item><title><![CDATA[Reply to remove_const für Template mit Spezialisierung on Thu, 05 Sep 2013 07:58:17 GMT]]></title><description><![CDATA[<p>Hi,</p>
<p>Sone:<br />
Cool, dankeschön. <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="🙂"
    /></p>
<p>Leider verstehe ich den Code nicht ganz. Wenn bei <code>is_specialization</code> Argumente mit T=O&lt;int&gt; und U=O reinkommen wie bei Deiner 3. <code>static_assert</code> -Zeile, wieso matcht er dann auf Deinen <code>is_specialization_impl</code> - <code>true_type</code> ? Die Spezialisierung besagt dort doch beim ersten Argument <code>U&lt;V&gt;</code> , was hier dann <code>O&lt;O&lt;int&gt;&gt;</code> . Hm, nagut, das ist ja valide. Aber mit T=NoTemplate, U=O (erste <code>static_assert</code> -Zeile), würde die Spezialisierung ja <code>O&lt;NoTemplate&gt;</code> als erstes Argument erhalten, was dann genau so valide erscheint.</p>
<p>Wäre super, wenn Du mich von meinen Irritationen/Denkfehlern befreien könntest. <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="🙂"
    /></p>
<p>camper:<br />
Du meinst, bei fak&lt;0&gt; instanziiert er fak&lt;-1&gt;? Wieso führt das dann nicht zur Endlosrekursion?</p>
<p>Zur Verkürzung: Stimmt, gar nicht bedacht, dass nur die TA-Typgleichheit gewährleistet sein muss, dankeschön. <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="🙂"
    /></p>
<p>Beste Grüße,<br />
Eisflamme</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2350431</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2350431</guid><dc:creator><![CDATA[Eisflamme]]></dc:creator><pubDate>Thu, 05 Sep 2013 07:58:17 GMT</pubDate></item><item><title><![CDATA[Reply to remove_const für Template mit Spezialisierung on Thu, 05 Sep 2013 08:49:51 GMT]]></title><description><![CDATA[<blockquote>
<p>Du meinst, bei fak&lt;0&gt; instanziiert er fak&lt;-1&gt;? Wieso führt das dann nicht zur Endlosrekursion?</p>
</blockquote>
<p>Tut es ja gerade. Der Code ist nicht gültig. Es führt zu einer sehr großen Template-Instantiierungstiefe.</p>
<blockquote>
<p>Wenn bei is_specialization Argumente mit T=O&lt;int&gt; und U=O reinkommen wie bei Deiner 3. static_assert-Zeile, wieso matcht er dann auf Deinen is_specialization_impl-true_type?</p>
</blockquote>
<p>Weil es passt? T wird bei der partiellen Spezialisierung <code>int</code> sein, und U=O. Daher matcht diese für alle Fälle, wo <code>U&lt;T&gt;</code> übergeben wird - T wird dann zum Argument von <code>U</code> deduziert.</p>
<blockquote>
<p>Aber mit T=NoTemplate, U=O (erste static_assert-Zeile), würde die Spezialisierung ja O&lt;NoTemplate&gt; als erstes Argument erhalten</p>
</blockquote>
<p>Nein! Denn T ist ja nicht <code>O&lt;NoTemplate&gt;</code> ! T ist NoTemplate, und daher passt das nicht.</p>
<p>Du weißt doch, wie partielle Spezialisierungen funktionieren? <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="🙂"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/2350438</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2350438</guid><dc:creator><![CDATA[Sone]]></dc:creator><pubDate>Thu, 05 Sep 2013 08:49:51 GMT</pubDate></item><item><title><![CDATA[Reply to remove_const für Template mit Spezialisierung on Thu, 05 Sep 2013 16:15:13 GMT]]></title><description><![CDATA[<p>@fak: Okay <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="🙂"
    /></p>
<p>@Deine Lösung:<br />
Hm, ich glaube, jetzt verstehe ich das, aber da ist der Compiler ja irgendwie schon ziemlich schlau?</p>
<p>Gut, die partielle Spezialisierung heißt, dass er versucht auf einen U&lt;T&gt;-Typ zu matchen. Also muss U schon Mal O sein und T kann er sich dann angeln (deduzieren). Hm, hm... das ist logisch. Mein Denkfehler war, dass ich dachte, wenn U&lt;T&gt; erwartet wird und es ein T = NoTemplate gibt, dass er sich dann einfach selbst einen Typ U&lt;NoTemplate&gt; basteln könnte. Der darf aber nicht basteln, sondern soll nur matchen und wenn ihm innendrin was fehlt (also das Innere von U&lt;.&gt;), dann darf er sich das eben aus dem Template-Argument ziehen.</p>
<p>Wenn jemand Lust hat, kann er das ja nochmal umformulieren oder versuchen es anders zu pointieren, auf alle Fälle glaube ich es jetzt verstanden zu haben, danke. <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="🙂"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/2350449</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2350449</guid><dc:creator><![CDATA[Eisflamme]]></dc:creator><pubDate>Thu, 05 Sep 2013 16:15:13 GMT</pubDate></item></channel></rss>