<?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[Vorschläge zu: Funktionen mit variabler Argumentenzahl gleichen Typs]]></title><description><![CDATA[<p>Hi,</p>
<p>ich hab mir letztens Gedanken darüber gemacht, wie man <em>am schönsten</em> eine Funktion mit beliebig vielen Argumenten <strong>eines Types</strong> umsetzen kann (alle C++11 features erlaubt).</p>
<p>Mit den ISO C Variadic Functions, meine Herren, möchte ich <a href="http://static.tumblr.com/3f01m0v/yNum64m53/gentleman.png" rel="nofollow"><em>nichts</em> zu tun haben</a>.</p>
<h1>Meine Ideen</h1>
<p>:</p>
<h2>std::initializer_list + variadic macros</h2>
<p><strong>Syntax:</strong></p>
<pre><code class="language-cpp">template&lt;typename T&gt;
//Falls explizit ein Typ gebraucht wird, den Template-Parameter des Containers durch den gewünschten Typ ersetzen und den Template-Teil wegfallen lassen...
void foo( std::vector&lt;T&gt; i )//Ein beliebiger STL-Container. Der std::initializer_list&lt;value_type&gt; const&amp; CTor ist selbstverständlich bei keinem explicit.
{
    //do some shit
}

#define foo(...) foo({__VA_ARGS__})
</code></pre>
<h2>Variadic templates + static assertions</h2>
<p><strong>Das Grundgerüst:</strong></p>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;type_traits&gt;
#include &lt;tuple&gt;

template&lt;typename&gt;
constexpr bool all_same()
{
        return true;
};

template&lt;typename T, typename T2, typename... Ts&gt;
constexpr bool all_same();

template&lt;typename T, typename T2, typename... Ts&gt;
struct predicate
{
        static constexpr bool value = std::is_same&lt;T, T2&gt;::value &amp;&amp; all_same&lt;T2, Ts...&gt;();
};

template&lt;typename T, typename T2, typename... Ts&gt;
constexpr bool all_same()
{
        return predicate&lt;T, T2, Ts...&gt;::value;
}

template&lt;typename ...T&gt;
using get_first = typename std::tuple_element&lt;0, std::tuple&lt;T...&gt;&gt;::type;

template&lt;typename ...T&gt;
void ensure_type_equality()
{
        static_assert(all_same&lt;T...&gt;(), &quot;All Template-Parameters have to have the same type!&quot;);
}
</code></pre>
<p><strong>Syntax</strong>:</p>
<pre><code class="language-cpp">template&lt;typename ...intT&gt;
void foo(intT... args)
{
        ensure_type_equality&lt;intT...&gt;();

        //opt. noch folgendes:

        std::vector&lt;first_of&lt;intT...&gt;&gt; v{ args... };//Und dann mit STL-Containern und Uniform-Initialization-Syntax/Dem initializer_list ctor arbeiten.
        //Auch hier kann der Typ (entweder durch static assertion oder durch den value_type des vectors) erzwungen werden.
}
</code></pre>
<p>Falls jemand eine Erklärung braucht, einfach nachfragen. Ich denke, die, die mir die Frage beantworten können (Kellerautomat, cooky, volkard (wo ist der Kerl), usw.) brauchen keine.</p>
<h2>Verwendung</h2>
<p><strong>Verwendung</strong> beider Varianten ist offensichtlich:</p>
<pre><code class="language-cpp">foo(1, 5, 8, 5, 7, myInt);
</code></pre>
<p>Bei beiden gleich.</p>
<p>---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------</p>
<p>Jetzt fragt sich, was die bessere, bzw. performantere Variante ist (ich denke, von der Performance dürften beide gleich schnell sein, abgesehen vom Compilieren).</p>
<p>Ich würde ohne Frage obige Variante vorziehen, jedoch sieht die so nach &quot;dirty hack&quot; aus. Außerdem mag ich Makros nicht, variadic templates dagegen schon sehr.</p>
<p>Gibt es noch weitere Möglichkeiten?</p>
<p>MfG</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/306827/vorschläge-zu-funktionen-mit-variabler-argumentenzahl-gleichen-typs</link><generator>RSS for Node</generator><lastBuildDate>Fri, 07 Aug 2026 06:14:42 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/306827.rss" rel="self" type="application/rss+xml"/><pubDate>Wed, 08 Aug 2012 12:04:19 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Vorschläge zu: Funktionen mit variabler Argumentenzahl gleichen Typs on Wed, 08 Aug 2012 12:08:06 GMT]]></title><description><![CDATA[<p>Hi,</p>
<p>ich hab mir letztens Gedanken darüber gemacht, wie man <em>am schönsten</em> eine Funktion mit beliebig vielen Argumenten <strong>eines Types</strong> umsetzen kann (alle C++11 features erlaubt).</p>
<p>Mit den ISO C Variadic Functions, meine Herren, möchte ich <a href="http://static.tumblr.com/3f01m0v/yNum64m53/gentleman.png" rel="nofollow"><em>nichts</em> zu tun haben</a>.</p>
<h1>Meine Ideen</h1>
<p>:</p>
<h2>std::initializer_list + variadic macros</h2>
<p><strong>Syntax:</strong></p>
<pre><code class="language-cpp">template&lt;typename T&gt;
//Falls explizit ein Typ gebraucht wird, den Template-Parameter des Containers durch den gewünschten Typ ersetzen und den Template-Teil wegfallen lassen...
void foo( std::vector&lt;T&gt; i )//Ein beliebiger STL-Container. Der std::initializer_list&lt;value_type&gt; const&amp; CTor ist selbstverständlich bei keinem explicit.
{
    //do some shit
}

#define foo(...) foo({__VA_ARGS__})
</code></pre>
<h2>Variadic templates + static assertions</h2>
<p><strong>Das Grundgerüst:</strong></p>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;type_traits&gt;
#include &lt;tuple&gt;

template&lt;typename&gt;
constexpr bool all_same()
{
        return true;
};

template&lt;typename T, typename T2, typename... Ts&gt;
constexpr bool all_same();

template&lt;typename T, typename T2, typename... Ts&gt;
struct predicate
{
        static constexpr bool value = std::is_same&lt;T, T2&gt;::value &amp;&amp; all_same&lt;T2, Ts...&gt;();
};

template&lt;typename T, typename T2, typename... Ts&gt;
constexpr bool all_same()
{
        return predicate&lt;T, T2, Ts...&gt;::value;
}

template&lt;typename ...T&gt;
using get_first = typename std::tuple_element&lt;0, std::tuple&lt;T...&gt;&gt;::type;

template&lt;typename ...T&gt;
void ensure_type_equality()
{
        static_assert(all_same&lt;T...&gt;(), &quot;All Template-Parameters have to have the same type!&quot;);
}
</code></pre>
<p><strong>Syntax</strong>:</p>
<pre><code class="language-cpp">template&lt;typename ...intT&gt;
void foo(intT... args)
{
        ensure_type_equality&lt;intT...&gt;();

        //opt. noch folgendes:

        std::vector&lt;first_of&lt;intT...&gt;&gt; v{ args... };//Und dann mit STL-Containern und Uniform-Initialization-Syntax/Dem initializer_list ctor arbeiten.
        //Auch hier kann der Typ (entweder durch static assertion oder durch den value_type des vectors) erzwungen werden.
}
</code></pre>
<p>Falls jemand eine Erklärung braucht, einfach nachfragen. Ich denke, die, die mir die Frage beantworten können (Kellerautomat, cooky, volkard (wo ist der Kerl), usw.) brauchen keine.</p>
<h2>Verwendung</h2>
<p><strong>Verwendung</strong> beider Varianten ist offensichtlich:</p>
<pre><code class="language-cpp">foo(1, 5, 8, 5, 7, myInt);
</code></pre>
<p>Bei beiden gleich.</p>
<p>---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------</p>
<p>Jetzt fragt sich, was die bessere, bzw. performantere Variante ist (ich denke, von der Performance dürften beide gleich schnell sein, abgesehen vom Compilieren).</p>
<p>Ich würde ohne Frage obige Variante vorziehen, jedoch sieht die so nach &quot;dirty hack&quot; aus. Außerdem mag ich Makros nicht, variadic templates dagegen schon sehr.</p>
<p>Gibt es noch weitere Möglichkeiten?</p>
<p>MfG</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2240027</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2240027</guid><dc:creator><![CDATA[Sone]]></dc:creator><pubDate>Wed, 08 Aug 2012 12:08:06 GMT</pubDate></item><item><title><![CDATA[Reply to Vorschläge zu: Funktionen mit variabler Argumentenzahl gleichen Typs on Wed, 08 Aug 2012 12:16:44 GMT]]></title><description><![CDATA[<p>Ich finde Funktionen mit variabler Anzahl an Parametern kacke. Gerade wenn sie gleichen Typs sind, dann ist ein Array oder vergleichbares sinnvoller. Ausnahmen bestaetigen die Regel.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2240034</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2240034</guid><dc:creator><![CDATA[knivil]]></dc:creator><pubDate>Wed, 08 Aug 2012 12:16:44 GMT</pubDate></item><item><title><![CDATA[Reply to Vorschläge zu: Funktionen mit variabler Argumentenzahl gleichen Typs on Wed, 08 Aug 2012 12:57:01 GMT]]></title><description><![CDATA[<ol>
<li>Makro? wäh. Wenn dann nimm die zwei geschweiften Klammern auf dich - und geh nicht erst den Umweg über vector oder ähnliches, initializer_list, reicht doch.</li>
</ol>
<pre><code class="language-cpp">template&lt;typename T&gt;
void foo( std::initializer_list&lt;T&gt; l )
{
    //do some shit
}

foo({1,2,meh});
</code></pre>
<p>Evtl. um die Syntax etwas geschemidiger zu machen statt der Funktion ein struct mit entsprechendem Ctor mit Nebenwirkungen - obwohl ich nur für die gesparten Klammern nicht sowas unschönes basteln würde:</p>
<pre><code class="language-cpp">struct foo
{
  template&lt;class T&gt;
  foo(std::initializer_list&lt;T&gt; l)
  { /*do stuff*/ }
};

foo{1,2,meh};
</code></pre>
<ol start="2">
<li>Ziemlicher Overkill oder? <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="😉"
    /><br />
Auch hier: warum den Umweg über vector? Du wirst eh in der Funktion eine Schleife über alle Elemente haben, dann ginge auch was in dieser Richtung:</li>
</ol>
<pre><code class="language-cpp">#include &lt;iostream&gt;
template &lt;class T&gt; struct FooIt 
{ 
  void do_stuff(T t) { std::cout &lt;&lt; t &lt;&lt; ' '; }

  template&lt;class U, class... Tail&gt;
  void doFooForEach(U&amp;&amp; u, Tail&amp;&amp;... args)
  { 
    do_stuff(std::forward&lt;U&gt;(u));
    doFoo(std::forward&lt;Tail&gt;(args)...);
  }
  void doFooForEach() {}
};

template &lt;class Head, class... T&gt;
void foo(Head&amp;&amp; h, T&amp;&amp;... args)
{ 
  FooIt&lt;Head&gt; theFooer; //&lt;&lt;- 1. parameter legt &quot;Bearbeitungstyp&quot; fest
  theFooer.doFooForEach(std::forward&lt;Head&gt;(h), std::forward&lt;T&gt;(args)...);
}

int main()
{
  short meh = 3;
  foo(1,2u,meh);
  foo(&quot;sic!&quot;);
  foo(3.14, meh); //double, short -&gt; kompatibel reicht ja wohl oder?
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2240056</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2240056</guid><dc:creator><![CDATA[pumuckl]]></dc:creator><pubDate>Wed, 08 Aug 2012 12:57:01 GMT</pubDate></item><item><title><![CDATA[Reply to Vorschläge zu: Funktionen mit variabler Argumentenzahl gleichen Typs on Wed, 08 Aug 2012 13:13:26 GMT]]></title><description><![CDATA[<p>pumuckl schrieb:</p>
<blockquote>
<ol start="2">
<li>Ziemlicher Overkill oder? <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="😉"
    /></li>
</ol>
</blockquote>
<p>Hehe <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f603.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--grinning_face_with_big_eyes"
      title=":D"
      alt="😃"
    /></p>
<p>pumuckl schrieb:</p>
<blockquote>
<p>Auch hier: warum den Umweg über vector?</p>
</blockquote>
<p><strong>ICH HABE ZUERST <code>INITIALIZER_LIST</code> GENOMMEN!</strong><br />
Aber dann dachte ich, ich will in der Funktion EH mit Sequentiellen Containern arbeiten, also... <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>pumuckl schrieb:</p>
<blockquote>
<p>Du wirst eh in der Funktion eine Schleife über alle Elemente haben, dann ginge auch was in dieser Richtung:</p>
</blockquote>
<p>Ja, s.o. wie gesagt, ich wollte einen Sequentiellen Container.</p>
<p>pumuckl schrieb:</p>
<blockquote>
<pre><code class="language-cpp">foo(3.14, meh); //double, short -&gt; kompatibel reicht ja wohl oder?
</code></pre>
</blockquote>
<p>Dann statt <code>is_same</code> eben <code>is_convertible</code> ;<br />
Wäre prinzipiell mehr was ich wollte.</p>
<p>Danke schonmal.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2240066</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2240066</guid><dc:creator><![CDATA[Sone]]></dc:creator><pubDate>Wed, 08 Aug 2012 13:13:26 GMT</pubDate></item><item><title><![CDATA[Reply to Vorschläge zu: Funktionen mit variabler Argumentenzahl gleichen Typs on Wed, 08 Aug 2012 13:16:01 GMT]]></title><description><![CDATA[<p>Um das schon vorweg zu nehmen:<br />
Das ist aus Spaß! Nichts, was ich in echten Programmen verwenden würde (da könnte man einfach ein start-end Iteratoren Paar nehmen).</p>
<p>Einfach nur um zu sehen was geht.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2240067</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2240067</guid><dc:creator><![CDATA[Sone]]></dc:creator><pubDate>Wed, 08 Aug 2012 13:16:01 GMT</pubDate></item><item><title><![CDATA[Reply to Vorschläge zu: Funktionen mit variabler Argumentenzahl gleichen Typs on Wed, 08 Aug 2012 13:47:20 GMT]]></title><description><![CDATA[<pre><code class="language-cpp">template&lt;class U, class... Tail&gt;
  void doFooForEach(U&amp;&amp; u, Tail&amp;&amp;... args)
  {
    do_stuff(std::forward&lt;U&gt;(u));
    doFoo(std::forward&lt;Tail&gt;(args)...);
  }
  void doFooForEach() {}
</code></pre>
<p>wird zu</p>
<pre><code class="language-cpp">template&lt;typename Func, typename... T&gt;
void doForEach(Func f, T&amp;&amp;... args)
{
    bool dummy[] = { (f(std::forward&lt;T&gt;(args)),false)..., false };
}
</code></pre>
<p>Perfect forwarding bedeutet ja nicht, dass der Aufruf plötzlich völlig kostenlos wird. Bei hinreichend vielen Parametern wird der Compiler vermutlich auch das Inlinen aufgeben.</p>
<p>Ansonsten kann man so etwas in Erwägung ziehen:</p>
<pre><code class="language-cpp">template &lt;typename... T&gt; struct all_convertible : std::true_type {};
template &lt;typename T, typename U, typename... V&gt; struct all_convertible&lt;T, U, V...&gt; : std::integral_constant&lt;bool, std::is_convertible&lt;U, T&gt;::value &amp;&amp; all_convertible&lt;T, V...&gt;::value&gt; {};

template &lt;typename T, typename... Args&gt;
auto fun(Args&amp;&amp;... x) -&gt; typename std::enable_if&lt;all_convertible&lt;T, Args...&gt;::value, T&gt;::type;

template &lt;typename... T&gt;
auto fun(T&amp;&amp;... x) -&gt; typename std::common_type&lt;T...&gt;::type
{
    return fun&lt;typename std::common_type&lt;T...&gt;::type&gt;( std::forward&lt;T&gt;(x)... ); // der andere Overload ist spezieller
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2240073</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2240073</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Wed, 08 Aug 2012 13:47:20 GMT</pubDate></item><item><title><![CDATA[Reply to Vorschläge zu: Funktionen mit variabler Argumentenzahl gleichen Typs on Wed, 08 Aug 2012 14:48:18 GMT]]></title><description><![CDATA[<p>camper schrieb:</p>
<blockquote>
<p>[...]wird zu</p>
<pre><code class="language-cpp">template&lt;typename Func, typename... T&gt;
void doForEach(Func f, T&amp;&amp;... args)
{
    bool dummy[] = { (f(std::forward&lt;T&gt;(args)),false)..., false };
}
</code></pre>
</blockquote>
<p>Njam <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/2240112</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2240112</guid><dc:creator><![CDATA[pumuckl]]></dc:creator><pubDate>Wed, 08 Aug 2012 14:48:18 GMT</pubDate></item></channel></rss>