<?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[template-Conditional]]></title><description><![CDATA[<p>Hallo.</p>
<p>Das gewöhnliche <code>std::conditional</code> für Typen dürfte bekannt sein. Für Werte gibt es den tenären <code>?:</code> -Operator. Wie löst man so etwas für Templates? In C++11 fällt mir nur eine Lösung für im Voraus definierte Template-Signaturen ein:</p>
<pre><code>template&lt;bool Condition, template&lt;int, int&gt; class T, template&lt;int, int&gt; class U&gt;
				struct Conditional
				{
					template&lt;int A, int B&gt;
					using Type = T&lt;A, B&gt;;
				};
				// false-Case analog
</code></pre>
<p>Mit &quot;im Voraus definierte&quot; meine ich, dass die Templates <code>T</code> und <code>U</code> dieselbe Signaturen haben müssen wie <code>Conditional</code> und dass <code>Conditional</code> nur eine Signatur akzeptieren kann, wobei man daher für jeden Anwendungsfall ein eigenes <code>Conditional</code> schreiben (oder von einem Makro generieren lassen) muss.</p>
<p>In C++03 (was ich eigentlich wollte) fällt mir gar keine befriedigende Lösung ein. Das, was noch am nächsten kommt, ist dies hier:</p>
<pre><code>template&lt;bool Condition, template&lt;int, int&gt; class T, template&lt;int, int&gt; class U&gt;
				struct Conditional
				{
					template&lt;int A, int  B&gt;
					struct Type : public T&lt;A, B&gt;
					{
					};
				};
				// false-Case analog
</code></pre>
<p>Gibt es für den spezifischen Fall eine gute C++03-Lösung und gibt es für eine Verallgemeinerung C++03- / C++11-Lösungen? Variadic Templates sind keine allgemeine Lösung, da Templates auch andere Templates oder, wie auch bei mir im tatsächlichen Code, Werte annehmen können.</p>
<p>Gruss.</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/329017/template-conditional</link><generator>RSS for Node</generator><lastBuildDate>Tue, 07 Jul 2026 07:38:30 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/329017.rss" rel="self" type="application/rss+xml"/><pubDate>Tue, 04 Nov 2014 13:27:24 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to template-Conditional on Tue, 04 Nov 2014 13:27:24 GMT]]></title><description><![CDATA[<p>Hallo.</p>
<p>Das gewöhnliche <code>std::conditional</code> für Typen dürfte bekannt sein. Für Werte gibt es den tenären <code>?:</code> -Operator. Wie löst man so etwas für Templates? In C++11 fällt mir nur eine Lösung für im Voraus definierte Template-Signaturen ein:</p>
<pre><code>template&lt;bool Condition, template&lt;int, int&gt; class T, template&lt;int, int&gt; class U&gt;
				struct Conditional
				{
					template&lt;int A, int B&gt;
					using Type = T&lt;A, B&gt;;
				};
				// false-Case analog
</code></pre>
<p>Mit &quot;im Voraus definierte&quot; meine ich, dass die Templates <code>T</code> und <code>U</code> dieselbe Signaturen haben müssen wie <code>Conditional</code> und dass <code>Conditional</code> nur eine Signatur akzeptieren kann, wobei man daher für jeden Anwendungsfall ein eigenes <code>Conditional</code> schreiben (oder von einem Makro generieren lassen) muss.</p>
<p>In C++03 (was ich eigentlich wollte) fällt mir gar keine befriedigende Lösung ein. Das, was noch am nächsten kommt, ist dies hier:</p>
<pre><code>template&lt;bool Condition, template&lt;int, int&gt; class T, template&lt;int, int&gt; class U&gt;
				struct Conditional
				{
					template&lt;int A, int  B&gt;
					struct Type : public T&lt;A, B&gt;
					{
					};
				};
				// false-Case analog
</code></pre>
<p>Gibt es für den spezifischen Fall eine gute C++03-Lösung und gibt es für eine Verallgemeinerung C++03- / C++11-Lösungen? Variadic Templates sind keine allgemeine Lösung, da Templates auch andere Templates oder, wie auch bei mir im tatsächlichen Code, Werte annehmen können.</p>
<p>Gruss.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2425731</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2425731</guid><dc:creator><![CDATA[Fytch]]></dc:creator><pubDate>Tue, 04 Nov 2014 13:27:24 GMT</pubDate></item><item><title><![CDATA[Reply to template-Conditional on Tue, 04 Nov 2014 13:53:25 GMT]]></title><description><![CDATA[<p>asfdlol schrieb:</p>
<blockquote>
<p>Wie löst man so etwas für Templates?</p>
</blockquote>
<p>Allgemein nicht.</p>
<p>asfdlol schrieb:</p>
<blockquote>
<p>In C++03 (was ich eigentlich wollte) fällt mir gar keine befriedigende Lösung ein. Das, was noch am nächsten kommt, ist dies hier:</p>
<pre><code>template&lt;bool Condition, template&lt;int, int&gt; class T, template&lt;int, int&gt; class U&gt;
				struct Conditional
				{
					template&lt;int A, int  B&gt;
					struct Type : public T&lt;A, B&gt;
					{
					};
				};
				// false-Case analog
</code></pre>
</blockquote>
<p>uhm, typedef? Type ist möglicherweise auch nicht die beste Wahl des Bezeichners, schliesslich handelt es sich ja nicht um einen Typen.</p>
<pre><code class="language-cpp">template&lt;bool Condition, template&lt;int, int&gt; class T, template&lt;int, int&gt; class U&gt;
				struct Conditional
				{
					template&lt;int A, int  B&gt;
					struct Apply
					{
						typedef T&lt;A,B&gt; Type;
					};
				};
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2425742</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2425742</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Tue, 04 Nov 2014 13:53:25 GMT</pubDate></item><item><title><![CDATA[Reply to template-Conditional on Tue, 04 Nov 2014 14:13:50 GMT]]></title><description><![CDATA[<p>Theoretisch sowas:<br />
<a href="http://ideone.com/hKE2GU" rel="nofollow">http://ideone.com/hKE2GU</a></p>
<pre><code>#include &lt;iostream&gt;
#include &lt;vector&gt;
#include &lt;list&gt;

template &lt;bool C, template &lt;typename...&gt; class A, template &lt;typename...&gt; class B&gt;
struct If
{
	template &lt;typename... AArgs&gt;
	using Type = A&lt;AArgs...&gt;;
};

template &lt;template &lt;typename...&gt; class A, template &lt;typename...&gt; class B&gt;
struct If&lt;false, A, B&gt;
{
	template &lt;typename... BArgs&gt;
	using Type = B&lt;BArgs...&gt;;
};

int main()
{
	If&lt;true, std::vector, std::list&gt;::Type&lt;int&gt; ct = { 23, 42 };
	If&lt;false, std::vector, std::list&gt;::Type&lt;double&gt; cf = { 3.14159, 13.37 };

	for (auto i : ct)
		std::cout &lt;&lt; i &lt;&lt; &quot;\n&quot;;
	for (auto d : cf)
		std::cout &lt;&lt; d &lt;&lt; &quot;\n&quot;;

	return 0;
}
</code></pre>
<p>Ich vermute aber, dass das mit Value-Templates (ala template &lt;int N&gt;) nicht funktionieren wird, kann mich aber irren.</p>
<p>EDIT: also ich habe es gerade nochmal mit std::array&lt;typename Type, size_t Size&gt; probiert und meine Vermutung hat sich bestätigt.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2425746</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2425746</guid><dc:creator><![CDATA[DrakoXP]]></dc:creator><pubDate>Tue, 04 Nov 2014 14:13:50 GMT</pubDate></item><item><title><![CDATA[Reply to template-Conditional on Tue, 04 Nov 2014 14:35:15 GMT]]></title><description><![CDATA[<p>camper schrieb:</p>
<blockquote>
<p>uhm, typedef? Type ist möglicherweise auch nicht die beste Wahl des Bezeichners, schliesslich handelt es sich ja nicht um einen Typen.</p>
<pre><code class="language-cpp">template&lt;bool Condition, template&lt;int, int&gt; class T, template&lt;int, int&gt; class U&gt;
				struct Conditional
				{
					template&lt;int A, int  B&gt;
					struct Apply
					{
						typedef T&lt;A,B&gt; Type;
					};
				};
</code></pre>
</blockquote>
<p>Das erzeugt nicht das Verhalten, das ich erreichen möchte. Auf diese Weise kann ich das ausgewählte Template nicht weiterreichen:</p>
<pre><code>#include &lt;iostream&gt;

template&lt;int, int&gt;
struct G1
{
	G1()
	{ 
		std::cout &lt;&lt; &quot;G1\n&quot;;
	}
};

template&lt;int, int&gt;
struct G2
{
	G2()
	{ 
		std::cout &lt;&lt; &quot;G2\n&quot;;
	}
};

template&lt;template&lt;int, int&gt; class T&gt;
struct Foo
{
	T&lt;7, 42&gt; M;
};

template&lt;bool Condition, template&lt;int, int&gt; class T, template&lt;int, int&gt; class U&gt; 
struct Conditional_asfdlol 
{ 
	template&lt;int A, int  B&gt; 
	struct Type : public T&lt;A, B&gt; 
	{ 
	}; 
};

template&lt;bool Condition, template&lt;int, int&gt; class T, template&lt;int, int&gt; class U&gt;
struct Conditional_camper
{
	template&lt;int A, int  B&gt;
	struct Apply
	{
		typedef U&lt;A,B&gt; Type;
	};
};

// Edit: Die false-Fälle braucht es in der Demonstration hier nicht. Habe es hardgecoded.

int main()
{
	Foo&lt;G1&gt; F1;
	Foo&lt;G2&gt; F2;

	Foo&lt;Conditional_asfdlol&lt;true, G1, G2&gt;::Type&gt; F3;
	Foo&lt;Conditional_camper&lt;false, G1, G2&gt;::Apply&gt; F4; // Nicht das gewünschte Ergebnis
}
</code></pre>
<p><a href="http://ideone.com/LAV7GW" rel="nofollow">http://ideone.com/LAV7GW</a><br />
Und <code>Apply</code> möchte / kann ich ja nicht schon in der <code>main</code> instanziieren, denn das ist die Aufgabe vom Nutzer <code>Foo</code> .</p>
<p>Dass <code>Type</code> unpassend gewählt wurde, stimmt.</p>
<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/10459">@DrakoXP</a><br />
Ja, an sowas dachte ich zuerst auch (siehe OP), aber gerade in meinem tatsächlichen Anwendungsfall habe ich es schon mit Nichttyp-Template-Parametern zu tun.</p>
<p>Edit: Deine Version (camper) würde in der Tat in C++03 gleich viel bieten wie die C++11- <code>using</code> -Lösung. Dazu müsste ich jedoch in <code>Foo</code> (und in allen anderen Nutzerklassen) auf <code>typename T&lt;...&gt;::Type</code> zugreifen statt direkt <code>T&lt;...&gt;</code> zu nutzen. Ich werde es mir überlegen.</p>
<p>Edit: Unsinn entfernt.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2425750</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2425750</guid><dc:creator><![CDATA[Fytch]]></dc:creator><pubDate>Tue, 04 Nov 2014 14:35:15 GMT</pubDate></item><item><title><![CDATA[Reply to template-Conditional on Tue, 04 Nov 2014 14:32:30 GMT]]></title><description><![CDATA[<p>asfdlol schrieb:</p>
<blockquote>
<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/10459">@DrakoXP</a><br />
Ja, an sowas dachte ich zuerst auch (siehe OP), aber gerade in meinem tatsächlichen Anwendungsfall habe ich es schon mit Nichttyp-Template-Parametern zu tun.</p>
</blockquote>
<p>Du wirst dir das wahrscheinlich denken können, aber als Workaround kann man,<br />
sofern der Typ aller Wert-Template-Parameter gleich ist, diesen auch als T... (z.B. int...) schreiben.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2425752</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2425752</guid><dc:creator><![CDATA[DrakoXP]]></dc:creator><pubDate>Tue, 04 Nov 2014 14:32:30 GMT</pubDate></item><item><title><![CDATA[Reply to template-Conditional on Tue, 04 Nov 2014 14:58:55 GMT]]></title><description><![CDATA[<p>DrakoXP schrieb:</p>
<blockquote>
<p>Du wirst dir das wahrscheinlich denken können, aber als Workaround kann man,<br />
sofern der Typ aller Wert-Template-Parameter gleich ist, diesen auch als T... (z.B. int...) schreiben.</p>
</blockquote>
<p>Nein, wusste ich nicht. Ich habe keine Ahnung von C++11. Aber danke für's Aufklären.</p>
<p>Ein weiterer (umständlicher und hässlicher) Workaround für C++11 wäre sowas hier: <a href="http://ideone.com/KNzR3d" rel="nofollow">http://ideone.com/KNzR3d</a></p>
<pre><code>#include &lt;type_traits&gt;
#include &lt;array&gt;
#include &lt;iostream&gt;

template&lt;bool Condition, template&lt;typename...&gt; class T, template&lt;typename...&gt; class U&gt;
struct Conditional
{
	template&lt;typename... Args&gt;
	using Type = T&lt;Args...&gt;;
};
template&lt;template&lt;typename...&gt; class T, template&lt;typename...&gt; class U&gt;
struct Conditional&lt;false, T, U&gt;
{
	template&lt;typename... Args&gt;
	using Type = U&lt;Args...&gt;;
};

template&lt;typename T, typename Size&gt;
using Array = std::array&lt;T, Size::value&gt;;

template&lt;typename T, typename Size&gt;
using BigArray = std::array&lt;T, Size::value * 2&gt;;

int main() 
{ 
	Conditional&lt;true, Array, BigArray&gt;::Type&lt;int, std::integral_constant&lt;std::size_t, 42&gt;&gt; Foo;
	std::cout &lt;&lt; Foo.size() &lt;&lt; '\n';

	Conditional&lt;false, Array, BigArray&gt;::Type&lt;int, std::integral_constant&lt;std::size_t, 42&gt;&gt; Bar;
	std::cout &lt;&lt; Bar.size() &lt;&lt; '\n';
}
</code></pre>
<p>Zunächst wollte ich die <code>integral_constant</code> s automatisch Entpacken mit <code>IsIntegralConstant</code> und einer wilden SFINAE-Konstruktion, aber man muss ja leider explizit <code>typename</code> angeben, was man durch kein Mittel in eine Kondition packen kann.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2425758</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2425758</guid><dc:creator><![CDATA[Fytch]]></dc:creator><pubDate>Tue, 04 Nov 2014 14:58:55 GMT</pubDate></item></channel></rss>