<?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[initializer_list und static_assert]]></title><description><![CDATA[<pre><code>template&lt;typename T, size_t N&gt;
class Vector
{
	private:
		T data[N];

	public:

		Vector(initializer_list&lt;T&gt; const&amp; init)
		{
			//static_assert(N == init.size(), &quot;&quot;);
		}
}
</code></pre>
<p>Das static_assert ist so nicht möglich, da init keine constant expression ist. Gibt es Tricks, mit denen eine statische Prüfung der Größe doch irgendwie möglich ist?</p>
<p>Bei std::array funktioniert es ja auch, allerdings hat ein Blick in den Header nicht weitergeholfen. Ist dort evtl. Compilermagie am Werk?</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/319624/initializer_list-und-static_assert</link><generator>RSS for Node</generator><lastBuildDate>Sat, 25 Jul 2026 04:10:21 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/319624.rss" rel="self" type="application/rss+xml"/><pubDate>Mon, 26 Aug 2013 14:10:33 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to initializer_list und static_assert on Mon, 26 Aug 2013 14:10:33 GMT]]></title><description><![CDATA[<pre><code>template&lt;typename T, size_t N&gt;
class Vector
{
	private:
		T data[N];

	public:

		Vector(initializer_list&lt;T&gt; const&amp; init)
		{
			//static_assert(N == init.size(), &quot;&quot;);
		}
}
</code></pre>
<p>Das static_assert ist so nicht möglich, da init keine constant expression ist. Gibt es Tricks, mit denen eine statische Prüfung der Größe doch irgendwie möglich ist?</p>
<p>Bei std::array funktioniert es ja auch, allerdings hat ein Blick in den Header nicht weitergeholfen. Ist dort evtl. Compilermagie am Werk?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2348603</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2348603</guid><dc:creator><![CDATA[Freddy Kruger]]></dc:creator><pubDate>Mon, 26 Aug 2013 14:10:33 GMT</pubDate></item><item><title><![CDATA[Reply to initializer_list und static_assert on Mon, 26 Aug 2013 14:17:03 GMT]]></title><description><![CDATA[<p>Hatten wir gerade erst <a href="http://www.c-plusplus.net/forum/319580" rel="nofollow">http://www.c-plusplus.net/forum/319580</a></p>
]]></description><link>https://www.c-plusplus.net/forum/post/2348608</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2348608</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Mon, 26 Aug 2013 14:17:03 GMT</pubDate></item><item><title><![CDATA[Reply to initializer_list und static_assert on Mon, 26 Aug 2013 17:38:37 GMT]]></title><description><![CDATA[<blockquote>
<p>Gibt es Tricks, mit denen eine statische Prüfung der Größe doch irgendwie möglich ist?</p>
</blockquote>
<p>Nein. Aber da du hier eine feste Anzahl an Parametern willst, bietet sich ein variadic template an.</p>
<pre><code>template&lt;typename T, size_t N&gt;
class Vector
{
    private:
        T data[N];

    public:

        template&lt;typename ... Types&gt;
        Vector( Types&amp;&amp;... args ) :
            data{ std::forward&lt;Types&gt;(args)... }
        {
            static_assert( sizeof...(Types) &lt;= N, &quot;&quot;);
        }
};
</code></pre>
<p>Funktioniert* dank §8.5.1/7.</p>
<p>~* (Ungetestet!)~</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2348623</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2348623</guid><dc:creator><![CDATA[Sone]]></dc:creator><pubDate>Mon, 26 Aug 2013 17:38:37 GMT</pubDate></item><item><title><![CDATA[Reply to initializer_list und static_assert on Mon, 26 Aug 2013 16:04:23 GMT]]></title><description><![CDATA[<p>Na damit geht's doch, warum sagst Du dann &quot;Nein&quot; <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>Btw: sizeof...(Types)</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2348657</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2348657</guid><dc:creator><![CDATA[Freddy Kruger]]></dc:creator><pubDate>Mon, 26 Aug 2013 16:04:23 GMT</pubDate></item><item><title><![CDATA[Reply to initializer_list und static_assert on Mon, 26 Aug 2013 17:39:15 GMT]]></title><description><![CDATA[<p>Nein, geht nicht mit C++11. GCC 4.8 bspw. deklariert alle Funktionen bereits <code>constexpr</code> , was aber nicht standardkonform ist. (s. §18.9/1)</p>
<p>Edit:</p>
<blockquote>
<p>Btw: sizeof...(Types)</p>
</blockquote>
<p>Danke. Ein Flüchtigkeitsfehler... <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/2348680</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2348680</guid><dc:creator><![CDATA[Sone]]></dc:creator><pubDate>Mon, 26 Aug 2013 17:39:15 GMT</pubDate></item><item><title><![CDATA[Reply to initializer_list und static_assert on Wed, 28 Aug 2013 09:48:25 GMT]]></title><description><![CDATA[<p>Dummerweise geht damit folgendes nicht mehr:</p>
<p>Vector&lt;float, 4&gt; v(1.0f, 2.0f, 0.0f, 1.0f);<br />
Vector&lt;float, 4&gt; w = v;</p>
<p>&quot;cannot convert 'Vector&lt;float, 4u&gt;' to 'float' in initialization|&quot;</p>
<p>Ein zustätzlicher Coopy-Constructor wird auch nicht aufgerufen.<br />
Ich glaube ich verzichte doch darauf...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2348957</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2348957</guid><dc:creator><![CDATA[Freddy Kruger]]></dc:creator><pubDate>Wed, 28 Aug 2013 09:48:25 GMT</pubDate></item><item><title><![CDATA[Reply to initializer_list und static_assert on Wed, 28 Aug 2013 10:07:59 GMT]]></title><description><![CDATA[<p>wie wär's mit</p>
<pre><code>template&lt;bool...B&gt; struct and_ : std::true_type {};
template&lt;bool...B&gt; struct and_&lt;false,B...&gt; : std::false_type {};
template&lt;bool...B&gt; struct and_&lt;true,B...&gt; : and_&lt;B...&gt; {};

template&lt;class T, size_t N&gt;
class Vector
{
    private:
        T data[N];

    public:
        template&lt;class...Types
            ,class = typename std::enable_if&lt;
                (sizeof...(Types)==N) &amp;&amp;
                and_&lt;std::is_convertible&lt;Types,T&gt;::value...&gt;::value
            &gt;::type
        &gt;
        explicit Vector(Types&amp;&amp;...args)
        : data{std::forward&lt;Types&gt;(args)...}
        {}
};
</code></pre>
<p>stattdessen? (auch ungetestet)</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2348962</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2348962</guid><dc:creator><![CDATA[krümelkacker]]></dc:creator><pubDate>Wed, 28 Aug 2013 10:07:59 GMT</pubDate></item><item><title><![CDATA[Reply to initializer_list und static_assert on Wed, 28 Aug 2013 10:13:41 GMT]]></title><description><![CDATA[<p>Freddy Kruger schrieb:</p>
<blockquote>
<p>Dummerweise geht damit folgendes nicht mehr:</p>
<p>Vector&lt;float, 4&gt; v(1.0f, 2.0f, 0.0f, 1.0f);<br />
Vector&lt;float, 4&gt; w = v;</p>
<p>&quot;cannot convert 'Vector&lt;float, 4u&gt;' to 'float' in initialization|&quot;</p>
</blockquote>
<p>Das liegt übrigens daran, dass der variadische Konstruktor bei der Überladungsauflösung gegenüber dem Kopierkonstruktor &quot;gewinnt&quot;, weil beim Kopierkonstruktor ja noch eine &quot;const-Konvertierung&quot; für v dabei ist.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2348964</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2348964</guid><dc:creator><![CDATA[krümelkacker]]></dc:creator><pubDate>Wed, 28 Aug 2013 10:13:41 GMT</pubDate></item><item><title><![CDATA[Reply to initializer_list und static_assert on Wed, 28 Aug 2013 11:17:53 GMT]]></title><description><![CDATA[<p>krümelkacker schrieb:</p>
<blockquote>
<p>Das liegt übrigens daran, dass der variadische Konstruktor bei der Überladungsauflösung gegenüber dem Kopierkonstruktor &quot;gewinnt&quot;, weil beim Kopierkonstruktor ja noch eine &quot;const-Konvertierung&quot; für v dabei ist.</p>
</blockquote>
<p>Völliger Blödsinn. Der Copy-Konstruktor wird bevorzugt, weil er kein <em>function-parameter-pack</em> hat. Dein Compiler, Freddy Krueger, ist einfach noch nicht aktuell genug. Siehe hier: GCC 4.8.1 kann es schon richtig: <a href="http://ideone.com/ewmqpP" rel="nofollow">http://ideone.com/ewmqpP</a></p>
<p>13.3.3.2/2 schrieb:</p>
<blockquote>
<p>a standard conversion sequence is a better conversion sequence than [...] an ellipsis conversion sequence</p>
</blockquote>
<p>Und überhaupt, <em>reference-compatible with added qualification</em> ist eine <em>identity conversion</em>.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2348973</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2348973</guid><dc:creator><![CDATA[Sone]]></dc:creator><pubDate>Wed, 28 Aug 2013 11:17:53 GMT</pubDate></item><item><title><![CDATA[Reply to initializer_list und static_assert on Wed, 28 Aug 2013 13:11:24 GMT]]></title><description><![CDATA[<p>Sone schrieb:</p>
<blockquote>
<p>13.3.3.2/2 schrieb:</p>
<blockquote>
<p>a standard conversion sequence is a better conversion sequence than [...] an ellipsis conversion sequence</p>
</blockquote>
</blockquote>
<p>Ich sehe hier nirgens eine &quot;ellipsis conversion&quot; sondern nur einen Pack-Expansion Operator. Dein Zitat ist also irrelevant.</p>
<p>Sone schrieb:</p>
<blockquote>
<p>Und überhaupt, <em>reference-compatible with added qualification</em> ist eine <em>identity conversion</em>.</p>
</blockquote>
<p>Ja und? Du sagst das so, als ob <a href="http://ideone.com/06cRYL" rel="nofollow">das hier</a> entweder zu einem Fehler (wegen Ambiguität) führen müsste, weil beides eine &quot;identity conversion&quot; ist, oder die normale foo-Funktion dran kommen müsste, weil sie kein Template ist. Offensichtlich ist dem nicht so. Und das, was dort passiert, ist dasselbe Problem in grün.</p>
<p>Das, was von deiner Erklärung übrig bleibt, ist die Sache mit der &quot;Variadität&quot; des Konstruktors. Aber die allein verhindert auch nicht, dass der Konstruktor zum Kopieren verwendet wird. Du hast nämlich gemogelt. Du hast den Konstruktor <code>explicit</code> gemacht. Das ist der einzige Grund, warum Dein letztes Beispiel mit der Kopierinitialisierung kompiliert. Entfernst du das <code>explicit</code> oder machst du aus der Kopierinitialisierung eine direkte, dann wird zum Konstruktor-Template aufgelöst, was dann einen Fehler produziert...</p>
<p>Fazit: Dein Beitrag war also</p>
<p>Sone schrieb:</p>
<blockquote>
<p>Völliger Blödsinn.</p>
</blockquote>
<p><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>
<p>Nächstes mal bitte die Klappe nicht soweit aufreißen. Danke.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2349004</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2349004</guid><dc:creator><![CDATA[krümelkacker]]></dc:creator><pubDate>Wed, 28 Aug 2013 13:11:24 GMT</pubDate></item><item><title><![CDATA[Reply to initializer_list und static_assert on Wed, 28 Aug 2013 13:42:50 GMT]]></title><description><![CDATA[<blockquote>
<p>Du hast nämlich gemogelt. Du hast den Konstruktor explicit gemacht. Das ist der einzige Grund, warum Dein letztes Beispiel mit der Kopierinitialisierung kompiliert. Entfernst du das explicit oder machst du aus der Kopierinitialisierung eine direkte, dann wird zum Konstruktor-Template aufgelöst, was dann einen Fehler produziert...</p>
</blockquote>
<p>Ahh.... da hast du völlig Recht. Wie konnt' ich das nur übersehen.</p>
<blockquote>
<p>Ja und? Du sagst das so, als ob <a href="http://ideone.com/06cRYL" rel="nofollow">das hier</a> entweder zu einem Fehler (wegen Ambiguität) führen müsste, weil beides eine &quot;identity conversion&quot; ist, oder die normale foo-Funktion dran kommen müsste, weil sie kein Template ist. Offensichtlich ist dem nicht so. Und das, was dort passiert, ist dasselbe Problem in grün.</p>
</blockquote>
<p>Das habe ich nie gesagt. Überhaupt, das hier wollte ich auch posten:</p>
<blockquote>
<p>Standard conversion sequence S1 is a better conversion sequence than standard conversion sequence S2 if [...] S1 and S2 are reference bindings (8.5.3), and the types to which the references refer are the same type except for top-level cv-qualifiers, and the type to which the reference initialized by S2 refers is more cv-qualified than the type to which the reference initialized by S1 refers.</p>
</blockquote>
<p>Ja, mein Missverstädnis lag wohl darin, dass ich immer dachte, mit dem Zitat</p>
<blockquote>
<p>An ellipsis conversion sequence occurs when an argument in a function call is matched with the ellipsis parameter specification of the function called</p>
</blockquote>
<p>Bezog sich der Standard auf alle Funktionen, die eine variable Anzahl von zuschüssigen Parametern erlauben - ob durch eine variadic function (wie bei C) oder ein <em>parameter-pack</em>.</p>
<blockquote>
<p>Nächstes mal bitte die Klappe nicht soweit aufreißen. Danke.</p>
</blockquote>
<p>Du weißt, ich mag das :p<br />
Das passiert so einmal im Monat, dann halte ich die nächste Weile die Klappe.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2349017</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2349017</guid><dc:creator><![CDATA[Sone]]></dc:creator><pubDate>Wed, 28 Aug 2013 13:42:50 GMT</pubDate></item><item><title><![CDATA[Reply to initializer_list und static_assert on Wed, 28 Aug 2013 14:40:33 GMT]]></title><description><![CDATA[<pre><code class="language-cpp">#include &lt;type_traits&gt;
#include &lt;cstddef&gt;
#include &lt;utility&gt;

template&lt;bool...B&gt; struct and_ : std::is_same&lt;and_&lt;true, B...&gt;, and_&lt;B..., true&gt;&gt; {};

template&lt;class T, size_t N&gt;
class Vector
{
    private:
        T data[N];

    public:
        template&lt;class...Types
            , typename std::enable_if&lt;
                (sizeof...(Types)==N) &amp;&amp; and_&lt;std::is_convertible&lt;Types,T&gt;::value...&gt;::value,
                int
            &gt;::type = 0
        &gt;
        Vector(Types&amp;&amp;...args)
        : data{std::forward&lt;Types&gt;(args)...}
        {}
};

Vector&lt;float, 4&gt; foo()
{
    return {1.0f, 2.0f, 0.0f, 1.0f};
}
</code></pre>
<p>Ist der Konstruktor explicit, kann foo nicht mehr so geschrieben werden. enable_if in einem non-type-Templateparameter zu verwenden, ist vorteilhaft, wenn mehrere Templates überladen werden sollen (man benötigt nicht zusätzliche Dummy-Parameter: der Typ des Templateparameters ist Teil der Signatur des Templates, ein Defaultargument dagegen nicht), und andernfalls genausogut wie in krümelkackers Version.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2349035</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2349035</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Wed, 28 Aug 2013 14:40:33 GMT</pubDate></item></channel></rss>