<?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[Variadic template expansion problem]]></title><description><![CDATA[<p>Hi Leute,<br />
ich bin auf ein Problem beim Umgang mit 'variadic templates' gestoßen.</p>
<pre><code>struct A { class Sub {}; };
struct B { class Sub {}; };
struct C { class Sub {}; };
</code></pre>
<p>Angenommen wir haben diese Klassenstruktur. In dem Fall drei verschiedene Klassen, die alle einen Klassentypen 'Sub' im Namespace haben.<br />
Man könnte also folgende Vererbung durchführen:</p>
<pre><code>class Foo : A::Sub, B::Sub, C::Sub {};
</code></pre>
<p>Hier böte sich ja ein template an:</p>
<pre><code>template&lt;typename... CLASSES&gt; class Foo : CLASSES::Sub... {};
</code></pre>
<p>Leider funktioniert das Entpacken der Parameterliste nicht, also der Teil 'CLASSES::Sub...'. Scheint eine Beschränkung der C++11 Spezifikation zu sein. Im Netz habe ich dazu auch keine verwertbaren Infos gefunden.</p>
<p>Ich könnte das natürlich jetzt rekursiv lösen:</p>
<pre><code>template&lt;class T, typename... LIST&gt; class ComposeClass : T, ComposeClass&lt;LIST...&gt; {}
template&lt;&gt; class ComposeClass&lt;class T&gt; : T {};
</code></pre>
<p>Das finde ich aber sehr unschön, da ich im realen Fall eine virtuelle Vererbung durchführen möchte. Das würde bei dieser Variante einen Rattenschwanz an vtables nach sich ziehen, da jede Mehrfachvererbung ein neues Interface darstellt, dass durch eine weitere &quot;Sub-vtable&quot; abgebildet wird.</p>
<p>Kennt jemand eine Lösung für das Problem, sodass ich diese Mehrfachvererbung via templates ohne Rekursion realisieren kann?</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/322439/variadic-template-expansion-problem</link><generator>RSS for Node</generator><lastBuildDate>Fri, 17 Jul 2026 22:38:46 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/322439.rss" rel="self" type="application/rss+xml"/><pubDate>Fri, 20 Dec 2013 12:59:49 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Variadic template expansion problem on Fri, 20 Dec 2013 12:59:49 GMT]]></title><description><![CDATA[<p>Hi Leute,<br />
ich bin auf ein Problem beim Umgang mit 'variadic templates' gestoßen.</p>
<pre><code>struct A { class Sub {}; };
struct B { class Sub {}; };
struct C { class Sub {}; };
</code></pre>
<p>Angenommen wir haben diese Klassenstruktur. In dem Fall drei verschiedene Klassen, die alle einen Klassentypen 'Sub' im Namespace haben.<br />
Man könnte also folgende Vererbung durchführen:</p>
<pre><code>class Foo : A::Sub, B::Sub, C::Sub {};
</code></pre>
<p>Hier böte sich ja ein template an:</p>
<pre><code>template&lt;typename... CLASSES&gt; class Foo : CLASSES::Sub... {};
</code></pre>
<p>Leider funktioniert das Entpacken der Parameterliste nicht, also der Teil 'CLASSES::Sub...'. Scheint eine Beschränkung der C++11 Spezifikation zu sein. Im Netz habe ich dazu auch keine verwertbaren Infos gefunden.</p>
<p>Ich könnte das natürlich jetzt rekursiv lösen:</p>
<pre><code>template&lt;class T, typename... LIST&gt; class ComposeClass : T, ComposeClass&lt;LIST...&gt; {}
template&lt;&gt; class ComposeClass&lt;class T&gt; : T {};
</code></pre>
<p>Das finde ich aber sehr unschön, da ich im realen Fall eine virtuelle Vererbung durchführen möchte. Das würde bei dieser Variante einen Rattenschwanz an vtables nach sich ziehen, da jede Mehrfachvererbung ein neues Interface darstellt, dass durch eine weitere &quot;Sub-vtable&quot; abgebildet wird.</p>
<p>Kennt jemand eine Lösung für das Problem, sodass ich diese Mehrfachvererbung via templates ohne Rekursion realisieren kann?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2372995</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2372995</guid><dc:creator><![CDATA[Hellhound66]]></dc:creator><pubDate>Fri, 20 Dec 2013 12:59:49 GMT</pubDate></item><item><title><![CDATA[Reply to Variadic template expansion problem on Fri, 20 Dec 2013 13:18:28 GMT]]></title><description><![CDATA[<p>Hellhound66 schrieb:</p>
<blockquote>
<p>Leider funktioniert das Entpacken der Parameterliste nicht,</p>
</blockquote>
<p>Ansonsten gute Beschreibung, aber das führt doch wieder zu einer Abwertung.<br />
Du schreibst nicht, was genau du getestet hast und mit welchem Compiler.</p>
<pre><code class="language-cpp">struct A { class Sub {}; };
struct B { class Sub {}; };
struct C { class Sub {}; };

template&lt;typename... CLASSES&gt; class Foo : CLASSES::Sub... {};

Foo&lt;A,B,C&gt; x;
</code></pre>
<p>Kein Problem mit g++ oder clang++ - sollte auch keine geben.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2372999</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2372999</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Fri, 20 Dec 2013 13:18:28 GMT</pubDate></item><item><title><![CDATA[Reply to Variadic template expansion problem on Wed, 11 Jun 2014 22:34:39 GMT]]></title><description><![CDATA[<p>...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2373010</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2373010</guid><dc:creator><![CDATA[Swordfish]]></dc:creator><pubDate>Wed, 11 Jun 2014 22:34:39 GMT</pubDate></item><item><title><![CDATA[Reply to Variadic template expansion problem on Fri, 20 Dec 2013 13:39:05 GMT]]></title><description><![CDATA[<p>Swordfish schrieb:</p>
<blockquote>
<p>Habs eben spaßeshalber mit MSVC 2013 ausprobiert:</p>
</blockquote>
<p>Swordfish schrieb:</p>
<blockquote>
<p>wtf?</p>
</blockquote>
<p>ist leider die korrekte Antwort (der Code ist i.O.)</p>
<p>Edit:<br />
geht es, wenn die Basisklasse explizit angegeben wird?</p>
<pre><code class="language-cpp">x.A::a = 1;
    x.B::b = 2;
    x.C::c = 3;
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2373013</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2373013</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Fri, 20 Dec 2013 13:39:05 GMT</pubDate></item><item><title><![CDATA[Reply to Variadic template expansion problem on Wed, 11 Jun 2014 22:34:45 GMT]]></title><description><![CDATA[<p>...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2373016</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2373016</guid><dc:creator><![CDATA[Swordfish]]></dc:creator><pubDate>Wed, 11 Jun 2014 22:34:45 GMT</pubDate></item><item><title><![CDATA[Reply to Variadic template expansion problem on Fri, 20 Dec 2013 13:52:44 GMT]]></title><description><![CDATA[<pre><code class="language-cpp">struct A { struct Sub { int a; }; };
struct B { struct Sub { int b; }; };
struct C { struct Sub { int c; }; };

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

template&lt;typename... CLASSES&gt; class Foo : public identity&lt;CLASSES&gt;::type::Sub... {};

Foo&lt;A, B, C&gt; x;
</code></pre>
<p>Das wäre ein Fix, der bei mir funktionieren würde...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2373018</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2373018</guid><dc:creator><![CDATA[decimad]]></dc:creator><pubDate>Fri, 20 Dec 2013 13:52:44 GMT</pubDate></item><item><title><![CDATA[Reply to Variadic template expansion problem on Fri, 20 Dec 2013 13:54:11 GMT]]></title><description><![CDATA[<p>sry, muss nat.</p>
<pre><code class="language-cpp">x.A::Sub::a = 1;
    x.B::Sub::b = 2;
    x.C::Sub::c = 3;
</code></pre>
<p>heißen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2373019</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2373019</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Fri, 20 Dec 2013 13:54:11 GMT</pubDate></item><item><title><![CDATA[Reply to Variadic template expansion problem on Fri, 20 Dec 2013 13:54:58 GMT]]></title><description><![CDATA[<p>Ich entschuldige mich für die läppische Formulierung zum Schluss hin.<br />
Die fehlenden Informationen folgen sofort:</p>
<p>Ich habe es mit MSVS2013 (v120) kompiliert. Das Problem ist dabei aber folgendes:<br />
1. Wenn ich die Schreibweise 'CLASSES::Sub...' nutze, scheint es zu funktionieren, ich habe allerdings keinen Zugriff auf XXX::Sub-Member. Also das gleiche Problem, wie Swordfish reproduziert hat.<br />
2. Wenn ich die Schreibweise 'CLASSES::...Sub&quot; nutze (ich weiß, falscher Syntax, aber was macht man nicht alles in seiner Verzweiflung), dann stürzt der Compiler mit einem internen Compilerfehler ab!</p>
<p>Meine Vermutung zu 1. ist, dass das Enpacken aus 'CLASSES::Sub...' folgendes macht: ': A, B, C::Sub', also das '::Sub' nicht in den Entpackvorgang einschließt. Könnte das der Fall sein?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2373020</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2373020</guid><dc:creator><![CDATA[Hellhound66]]></dc:creator><pubDate>Fri, 20 Dec 2013 13:54:58 GMT</pubDate></item><item><title><![CDATA[Reply to Variadic template expansion problem on Fri, 20 Dec 2013 13:56:04 GMT]]></title><description><![CDATA[<p>Mir ist in der Preview schon aufgefallen, dass die Expansion von Packs ab und zu etwas buggy ist, aber seit der Vollversion habe ich soetwas nicht wieder versucht... Schreibst Du einen Bugreport auf Connect? Zur Not reiche ich das ein...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2373021</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2373021</guid><dc:creator><![CDATA[decimad]]></dc:creator><pubDate>Fri, 20 Dec 2013 13:56:04 GMT</pubDate></item><item><title><![CDATA[Reply to Variadic template expansion problem on Fri, 20 Dec 2013 14:04:40 GMT]]></title><description><![CDATA[<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/6072">@Hellhound</a> ... Ich habe testweise auch mal Member in die &quot;Container-Klasse&quot; gepackt, die waren auch nicht erreichbar. Ich denke, das ist eher ein Fehler im Member-Lookup, weil das sizeof auch passt...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2373024</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2373024</guid><dc:creator><![CDATA[decimad]]></dc:creator><pubDate>Fri, 20 Dec 2013 14:04:40 GMT</pubDate></item><item><title><![CDATA[Reply to Variadic template expansion problem on Fri, 20 Dec 2013 14:07:49 GMT]]></title><description><![CDATA[<p>Ich korrigiere mich, das sizeof sieht auch merkwürdig aus.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2373026</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2373026</guid><dc:creator><![CDATA[decimad]]></dc:creator><pubDate>Fri, 20 Dec 2013 14:07:49 GMT</pubDate></item><item><title><![CDATA[Reply to Variadic template expansion problem on Fri, 20 Dec 2013 14:14:29 GMT]]></title><description><![CDATA[<p>Joar, es sieht so aus, dass der Compiler da überhaupt nicht expandiert, weil Sub kein Pack ist und erst wenn man das identity da reinklatscht, dann versucht er Classes zu expandieren.<br />
sizeof(Foo&lt;A,B,C&gt;) ist 1...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2373030</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2373030</guid><dc:creator><![CDATA[decimad]]></dc:creator><pubDate>Fri, 20 Dec 2013 14:14:29 GMT</pubDate></item><item><title><![CDATA[Reply to Variadic template expansion problem on Wed, 11 Jun 2014 22:36:31 GMT]]></title><description><![CDATA[<p>...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2373035</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2373035</guid><dc:creator><![CDATA[Swordfish]]></dc:creator><pubDate>Wed, 11 Jun 2014 22:36:31 GMT</pubDate></item><item><title><![CDATA[Reply to Variadic template expansion problem on Fri, 20 Dec 2013 14:26:42 GMT]]></title><description><![CDATA[<p>Naja, der Fix steht ja da... Unschön, aber immerhin macht es nicht so viel Arbeit, wie ein komplettes Subsystem auszutauschen, weil irgendein neues Feature mit virtuellen Basisklassen clasht... Oder weil nullptr nicht konstant sein sollen...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2373039</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2373039</guid><dc:creator><![CDATA[decimad]]></dc:creator><pubDate>Fri, 20 Dec 2013 14:26:42 GMT</pubDate></item><item><title><![CDATA[Reply to Variadic template expansion problem on Fri, 20 Dec 2013 14:29:16 GMT]]></title><description><![CDATA[<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/34233">@decimad</a>:<br />
Dank Deines Workarounds mit dem identity-template klappt das wunderbar.</p>
<p>Ich bin schon mehrfach über das Problem gestoßen, dass ich eine Kern-klasse habe, nennen wir sie Core, für die ich ein Interface zum Zugriff auf ebendiese Kernfunktionen bereitstelle. Jetzt kommt es immer mal wieder vor, dass ich Core um weitere Funktionen erweitern möchte, die für sich zusammengefasst eine neue logische Gruppierung bilden, aber vom Umfang her es sich kaum lohnt, dafür ein neues zusätzliches Interface bereitzustellen. Jetzt könnte ich diese natürlich in Core und dem Interface für Core (nennen wir es ICore) mit aufnehmen. Dann könnte Core aber sehr schnell unübersichtlich werden.<br />
Deshalb habe ich mir gedacht, wenn ich mir die Core-Klasse automatisch mit einem Template aus mehreren Unterklassen zusammenbauen lassen könnte, dass mir auch automatisch ein passendes Interface zur Verfügung stellt, wäre das für mich sehr übersichtlich und praktisch.</p>
<p>Wenn ich als Bedingung ansetze, dass die Modulklassen, aus denen Core zusammengesetzt wird '::Interface' und '::Module' enthalten, kann ich mir das bei der Komposition der Coreklasse zunutze machen. Hier mal zwei Module als Beispiel:</p>
<pre><code>struct A {
	class Interface {
	public:
		virtual void foo(void) = 0;
	};

	class Module : public virtual Interface	{
	public:
		virtual void foo(void) { std::cerr &lt;&lt; &quot;foo A\n&quot;; }
                void foo2(void) {/*....*/} // Not accessible via Interface
	};
};

struct B {
	class Interface {
	public:
		virtual void bar(void) = 0;
		virtual void bar2(void) = 0;
	};

	class Module : public virtual Interface	{
	public:
		virtual void bar(void) { std::cerr &lt;&lt; &quot;bar B\n&quot;; }
		virtual void bar2(void) { std::cerr &lt;&lt; &quot;bar2 B\n&quot;; }
	};
};
</code></pre>
<p>Jetzt baue ich mir automatisch eine Core-Klasse, die ein komplettes Interface zur Verfügung stellt zusammen:</p>
<pre><code>// identity template from decimad (C++.de Forum)
template&lt;typename T&gt; 
struct identity { 
    using type = T; 
}; 

template&lt;typename... MODULES&gt;
struct CoreModule {
	class Interface : virtual public identity&lt;MODULES&gt;::type::Interface...  {};
	class Module : public Interface, public identity&lt;MODULES&gt;::type::Module... {};
};

typedef CoreModule&lt;A, B&gt; CoreClass;
typedef CoreClass::Interface ICore;
typedef CoreClass::Module Core;
</code></pre>
<p>Ich kann jetzt ein Objekt vom Typ 'Core' instanzieren und den restriktierten Zugriff über das komponierte Interface 'ICore' bereitstellen. 'Core' selbst ist auch kompatibel zu den jeweiligen Modul-Interfaces 'A::Interface' und 'B::Interface', falls man in einer Subroutine nur einen Zugriff auf Teile von Core zulassen möchte.</p>
<pre><code>void test(ICore* core) {
	core-&gt;foo();
	core-&gt;bar();
}

void test2(A::Interface* a) { a-&gt;foo(); }

int _tmain(int argc,_TCHAR* argv[]) {
	ICore* core = new Core();
	test(core);
	test2(core);
        delete core;
	std::cin.get();
	return 0;
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2373041</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2373041</guid><dc:creator><![CDATA[Hellhound66]]></dc:creator><pubDate>Fri, 20 Dec 2013 14:29:16 GMT</pubDate></item><item><title><![CDATA[Reply to Variadic template expansion problem on Fri, 20 Dec 2013 14:42:05 GMT]]></title><description><![CDATA[<p>Ich würde Dir ans Herz legen, einen Weg zu finden, das ohne virtuelle Basisklassen umzusetzen, die meisten Fälle kann man seit Variadics auch mit &quot;statischen&quot; Funktionen umsetzen. Ich gebe den Ratschlag, denn Funktionszeiger als Template-Argumente, die man irgendwann einmal einsetzen möchte, weil mehrdeutige Interface-Funktionen einfach nur nerven, zu einem internen Compilerfehler führen.</p>
<p>Siehe:<br />
<a href="https://connect.microsoft.com/VisualStudio/feedback/details/809367/visual-c-internal-compiler-error-with-virtual-base-class" rel="nofollow">https://connect.microsoft.com/VisualStudio/feedback/details/809367/visual-c-internal-compiler-error-with-virtual-base-class</a></p>
]]></description><link>https://www.c-plusplus.net/forum/post/2373047</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2373047</guid><dc:creator><![CDATA[decimad]]></dc:creator><pubDate>Fri, 20 Dec 2013 14:42:05 GMT</pubDate></item><item><title><![CDATA[Reply to Variadic template expansion problem on Fri, 20 Dec 2013 15:04:55 GMT]]></title><description><![CDATA[<p>Danke für den Hinweis.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2373049</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2373049</guid><dc:creator><![CDATA[Hellhound66]]></dc:creator><pubDate>Fri, 20 Dec 2013 15:04:55 GMT</pubDate></item><item><title><![CDATA[Reply to Variadic template expansion problem on Fri, 20 Dec 2013 15:12:00 GMT]]></title><description><![CDATA[<p>In der Tat wäre ich eigentlich dafür, virtuelle Basisklassen aus dem Standard zu schmeißen, zumindest dann, wenn sie im Moment der einzige Grund dafür sind, dass offsetof nur bei POD-Typen funktioniert. Das hier wäre der ideale Einsatz für camper, der weiß da bestimmt mehr <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/2373052</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2373052</guid><dc:creator><![CDATA[decimad]]></dc:creator><pubDate>Fri, 20 Dec 2013 15:12:00 GMT</pubDate></item><item><title><![CDATA[Reply to Variadic template expansion problem on Fri, 20 Dec 2013 15:14:43 GMT]]></title><description><![CDATA[<p>Und ja, ich weiß, dann müsste man auch die Streams rausschmeißen: Ja, bitte, da habe ich in etwa dieselbe Meinung wie der Nichtmember in dem aktuellen anderen facet-Thread da...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2373054</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2373054</guid><dc:creator><![CDATA[decimad]]></dc:creator><pubDate>Fri, 20 Dec 2013 15:14:43 GMT</pubDate></item></channel></rss>