<?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[Array-Member initialisieren]]></title><description><![CDATA[<p>Hi, ich habe folgendes Problem:</p>
<pre><code class="language-cpp">class base { /* viele Konstruktoren */ };

class intermediate : public base {
   std::array&lt;...&gt; member;
   std::array&lt;...&gt; foo;
};

class derived : public intermediate { /* soll selbe Konstruktoren haben wie base */ };
</code></pre>
<p><code>derived</code> hat keine Member, seine Konstruktoren sind daher trivial. Ich würde also gerne in <code>derived</code> die Konstruktoren von <code>base</code> erben. Ich kann nur Konstruktoren der jeweils nächsten Elternklasse erben, d.h. <code>intermediate</code> muss auch alle Konstruktoren von <code>base</code> erben, damit er sie an <code>derived</code> weiter vererben kann. Also:</p>
<pre><code class="language-cpp">class intermediate : public base {
   std::array&lt;...&gt; member;
   std::array&lt;...&gt; foo;
public:
   using base::base;
};

class derived : public intermediate {
public:
   using intermediate::intermediate;
};
</code></pre>
<p>Jetzt bleibt das Problem, dass die Arrays nicht initialisiert sind. Wenn ich jetzt anfange, irgendwelche Konstruktoren zu schreiben, ist die gesamte Vererbung dahin (entweder man erbt alle Konstruktoren oder garkeine <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f621.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--pouting_face"
      title=":rage:"
      alt="😡"
    /> ) und ich muss in <code>derived</code> auch alle Konstruktoren ausschreiben. Es wäre also besser, ich könnte alle Konstruktoren schön vom Compiler generieren lassen, um Boilerplate zu sparen. Die Möglichkeit, die ich habe, ist natürlich in-class Initialization:</p>
<pre><code class="language-cpp">class intermediate : public base {
   std::array&lt;...&gt; member{ }; // Value-Initialized
   std::array&lt;...&gt; foo{ ... }; // siehe unten
public:
   using base::base;
};
</code></pre>
<p>So würde das funktionieren, aber jetzt kommt mein Problem:<br />
Das zweite Array soll in jedem Element einen Pointer auf das jeweilige Element im ersten Array besitzen (die Arraygrößen sind Template-Parameter, es muss also alles dynamisch sein).<br />
Ich habe mir folgendes Template-Meta-Programm dafür geschrieben:</p>
<pre><code class="language-cpp">#include &lt;array&gt;

template &lt;typename T, int N, int... Ns&gt;
struct array_gen : public array_gen&lt;T, N - 1, N - 1, Ns...&gt; { };

template &lt;typename T, int... Ns&gt;
struct array_gen&lt;T, 0, Ns...&gt; {
	static constexpr std::array&lt;T*, sizeof...(Ns)&gt; pointers(std::array&lt;T, sizeof...(Ns)&gt;&amp; a) {
		return { { &amp;a[Ns]... } };
	}
};

template &lt;int N&gt;
struct intermediate {
	using warum_das = array_gen&lt;int, N&gt;;

	std::array&lt;int, N&gt; arr{ };
	std::array&lt;int*, N&gt; a = warum_das::pointers(arr);
};

int main() {
	intermediate&lt;5&gt; t;
}
</code></pre>
<p>Hier eine Frage: Warum muss ich einen Typ-Alias <code>warum_das</code> benutzen und kann nicht direkt <code>array_gen&lt;int, N&gt;::pointers(arr)</code> schreiben? Sowohl Visual Studio 2015 als auch der GCC murren, clang frisst es. Welcher Compiler ist verbuggt?</p>
<p>Das würde funktionieren, aber es bricht in dem Moment zusammen, wenn ich kein Array von Pointern will, sondern ein Array von <code>std::atomic&lt;int*&gt;</code> möchte, denn Atomics können nicht kopiert werden. Was kann ich tun?</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/333395/array-member-initialisieren</link><generator>RSS for Node</generator><lastBuildDate>Sun, 26 Apr 2026 23:51:12 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/333395.rss" rel="self" type="application/rss+xml"/><pubDate>Thu, 02 Jul 2015 09:22:42 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Array-Member initialisieren on Thu, 02 Jul 2015 09:22:42 GMT]]></title><description><![CDATA[<p>Hi, ich habe folgendes Problem:</p>
<pre><code class="language-cpp">class base { /* viele Konstruktoren */ };

class intermediate : public base {
   std::array&lt;...&gt; member;
   std::array&lt;...&gt; foo;
};

class derived : public intermediate { /* soll selbe Konstruktoren haben wie base */ };
</code></pre>
<p><code>derived</code> hat keine Member, seine Konstruktoren sind daher trivial. Ich würde also gerne in <code>derived</code> die Konstruktoren von <code>base</code> erben. Ich kann nur Konstruktoren der jeweils nächsten Elternklasse erben, d.h. <code>intermediate</code> muss auch alle Konstruktoren von <code>base</code> erben, damit er sie an <code>derived</code> weiter vererben kann. Also:</p>
<pre><code class="language-cpp">class intermediate : public base {
   std::array&lt;...&gt; member;
   std::array&lt;...&gt; foo;
public:
   using base::base;
};

class derived : public intermediate {
public:
   using intermediate::intermediate;
};
</code></pre>
<p>Jetzt bleibt das Problem, dass die Arrays nicht initialisiert sind. Wenn ich jetzt anfange, irgendwelche Konstruktoren zu schreiben, ist die gesamte Vererbung dahin (entweder man erbt alle Konstruktoren oder garkeine <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f621.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--pouting_face"
      title=":rage:"
      alt="😡"
    /> ) und ich muss in <code>derived</code> auch alle Konstruktoren ausschreiben. Es wäre also besser, ich könnte alle Konstruktoren schön vom Compiler generieren lassen, um Boilerplate zu sparen. Die Möglichkeit, die ich habe, ist natürlich in-class Initialization:</p>
<pre><code class="language-cpp">class intermediate : public base {
   std::array&lt;...&gt; member{ }; // Value-Initialized
   std::array&lt;...&gt; foo{ ... }; // siehe unten
public:
   using base::base;
};
</code></pre>
<p>So würde das funktionieren, aber jetzt kommt mein Problem:<br />
Das zweite Array soll in jedem Element einen Pointer auf das jeweilige Element im ersten Array besitzen (die Arraygrößen sind Template-Parameter, es muss also alles dynamisch sein).<br />
Ich habe mir folgendes Template-Meta-Programm dafür geschrieben:</p>
<pre><code class="language-cpp">#include &lt;array&gt;

template &lt;typename T, int N, int... Ns&gt;
struct array_gen : public array_gen&lt;T, N - 1, N - 1, Ns...&gt; { };

template &lt;typename T, int... Ns&gt;
struct array_gen&lt;T, 0, Ns...&gt; {
	static constexpr std::array&lt;T*, sizeof...(Ns)&gt; pointers(std::array&lt;T, sizeof...(Ns)&gt;&amp; a) {
		return { { &amp;a[Ns]... } };
	}
};

template &lt;int N&gt;
struct intermediate {
	using warum_das = array_gen&lt;int, N&gt;;

	std::array&lt;int, N&gt; arr{ };
	std::array&lt;int*, N&gt; a = warum_das::pointers(arr);
};

int main() {
	intermediate&lt;5&gt; t;
}
</code></pre>
<p>Hier eine Frage: Warum muss ich einen Typ-Alias <code>warum_das</code> benutzen und kann nicht direkt <code>array_gen&lt;int, N&gt;::pointers(arr)</code> schreiben? Sowohl Visual Studio 2015 als auch der GCC murren, clang frisst es. Welcher Compiler ist verbuggt?</p>
<p>Das würde funktionieren, aber es bricht in dem Moment zusammen, wenn ich kein Array von Pointern will, sondern ein Array von <code>std::atomic&lt;int*&gt;</code> möchte, denn Atomics können nicht kopiert werden. Was kann ich tun?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2458500</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2458500</guid><dc:creator><![CDATA[Jodocus]]></dc:creator><pubDate>Thu, 02 Jul 2015 09:22:42 GMT</pubDate></item><item><title><![CDATA[Reply to Array-Member initialisieren on Thu, 02 Jul 2015 10:06:20 GMT]]></title><description><![CDATA[<p><a href="http://melpon.org/wandbox/permlink/TSQqNDOPVesaLPNX" rel="nofollow">Kompiliert in HEAD</a>. (Der relevante Bug-report für GCC findet sich <a href="https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52595" rel="nofollow">hier</a>)</p>
<p>Das wurde übrigens von <a href="http://open-std.org/JTC1/SC22/WG21/docs/cwg_active.html#325" rel="nofollow">CWG #325</a> behandelt; Die Problematik besteht darin, dass name lookup erst feststellen muss, dass <code>std::array</code> ein Template ist, sodass das Komma nicht einen neuen Deklarator (mit invalidem Initializer) einführt.</p>
<p>Zu deiner zweiten Frage:</p>
<p>§8.5.1/2 schrieb:</p>
<blockquote>
<p>Each member is copy-initialized from the corresponding <em>initializer-clause</em>.</p>
</blockquote>
<p>I.e.</p>
<pre><code>std::array&lt;std::atomic&lt;int*&gt;&gt; arr = {0, 0};
</code></pre>
<p>initialisiert jedes Element via</p>
<pre><code>std::atomic&lt;int*&gt; elem = 0;
</code></pre>
<p>Jedoch muss für diesen Fall eine temporäre Kopie erstellt und mit dieser initialisiert werden (§8.5/(17.6.2)). Das funktioniert offensichtlich nicht. Du kannst aber stattdessen eine eigene Array-Klasse basteln, die eine <code>initializer_list&lt;T&gt;</code> als Konstruktor-Argument nimmt und damit das Array befüllt.</p>
<p>Also e.g. (unvollständig!):</p>
<pre><code>#include &lt;array&gt;
#include &lt;atomic&gt;

template &lt;typename T, std::size_t N&gt;
struct Array : std::array&lt;T, N&gt; {
	template &lt;typename U&gt;
	constexpr Array(std::initializer_list&lt;U&gt; ilist) {
		auto p = std::array&lt;T, N&gt;::begin();
		for (auto iter = ilist.begin(); iter != ilist.end(); ++iter)
			*p++ = std::move(*iter);
	}
};

int main() {
	int i;
	Array&lt;std::atomic&lt;int*&gt;, 2&gt; arr = {(int*)nullptr, &amp;i};
}
</code></pre>
<p>Ohne den Cast geht es übrigens nicht, da inkonsistente Typen in diesem Fall sofort in einem Fehler resultieren. Nicht besonders hübsch, aber naja.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2458504</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2458504</guid><dc:creator><![CDATA[Columbo]]></dc:creator><pubDate>Thu, 02 Jul 2015 10:06:20 GMT</pubDate></item><item><title><![CDATA[Reply to Array-Member initialisieren on Thu, 02 Jul 2015 11:25:14 GMT]]></title><description><![CDATA[<p>Danke für deine Hilfe (und die Links).<br />
Wenn ich das mit meinem TMP-Schnipsel verbinde, gibt's aber wieder Probleme:</p>
<pre><code class="language-cpp">#include &lt;array&gt;
#include &lt;atomic&gt;
#include &lt;initializer_list&gt;

template &lt;typename T, std::size_t N&gt;
struct my_array final : std::array&lt;T, N&gt; {
	template &lt;typename U&gt;
	constexpr my_array(std::initializer_list&lt;U&gt; list) {
		auto iter = std::begin(*this);
		for(auto&amp; elem : list)
			*iter++ = std::move(elem);
	}
};

template &lt;typename T, int N, int... Ns&gt;
struct array_gen : public array_gen&lt;T, N - 1, N - 1, Ns...&gt; { };

template &lt;typename T, int... Ns&gt;
struct array_gen&lt;T, 0, Ns...&gt; {
	static constexpr std::initializer_list&lt;T*&gt; pointers(std::array&lt;T, sizeof...(Ns)&gt;&amp; a) {
		return { &amp;a[Ns]... };
	}
};

template &lt;int N&gt;
struct test {
	std::array&lt;int, N&gt; arr{ };
	my_array&lt;std::atomic&lt;int*&gt;, N&gt; a{ array_gen&lt;int, N&gt;::pointers(arr) };
};

int main() {
	test&lt;5&gt; t;
}
</code></pre>
<p>Jetzt wird das Template-Argument des Array-Konstruktors selbst als <code>initializer_list</code> aufgelöst, so ein Blödsinn, da der Compiler sinnigerweise bei braced initialization den verfügbaren Initializer-List-Konstruktor aufruft:</p>
<pre><code class="language-cpp">int main() {
   std::array&lt;int, 3&gt; arr{ };
   my_array&lt;std::atomic&lt;int*&gt;, 3&gt; a{array_gen&lt;int, 3&gt;::pointers(arr)}; // klappt nicht
   my_array&lt;std::atomic&lt;int*&gt;, 3&gt; a(array_gen&lt;int, 3&gt;::pointers(arr)); // klappt
};
</code></pre>
<p>Im ersten Fall sieht der Compiler nur: Braced initialization, nehme <code>initializer_list</code> -Konstruktor, löse Parameter nach <code>decltype(array_gen&lt;int, 3&gt;::pointers(arr))</code> auf, im zweiten Fall löst er den Template-Parameter richtig auf. Ich kann aber nur die erste Syntax für in-class initialization nutzen und für einen Template-Konstruktor kann man keine expliziten Template-Parameter angeben. Langsam nervt mich C++ mit seinen dämlichen initializer_list/uniform initialization-Konflikten. <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f621.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--pouting_face"
      title=":rage:"
      alt="😡"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/2458523</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2458523</guid><dc:creator><![CDATA[Jodocus]]></dc:creator><pubDate>Thu, 02 Jul 2015 11:25:14 GMT</pubDate></item><item><title><![CDATA[Reply to Array-Member initialisieren on Thu, 02 Jul 2015 11:42:58 GMT]]></title><description><![CDATA[<p>Naja, da ich dieses eigene Array eh niemals außer hier brauche, kann ich das Problem umschiffen, indem ich es auf Atomics festnagel und das Template entferne:</p>
<pre><code class="language-cpp">template &lt;typename T, std::size_t N&gt;
struct my_array final : std::array&lt;std::atomic&lt;T&gt;, N&gt; {
	constexpr my_array(std::initializer_list&lt;T&gt; list) {
		auto iter = std::begin(*this);
		for(auto&amp; elem : list)
			*iter++ = std::move(elem);
	}
};
</code></pre>
<p>So kompiliert es und macht, was es soll.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2458526</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2458526</guid><dc:creator><![CDATA[Jodocus]]></dc:creator><pubDate>Thu, 02 Jul 2015 11:42:58 GMT</pubDate></item><item><title><![CDATA[Reply to Array-Member initialisieren on Thu, 02 Jul 2015 11:50:32 GMT]]></title><description><![CDATA[<p>Huch, da fällt mir was viel hübscheres ein:</p>
<pre><code>template &lt;std::size_t N, typename=std::make_index_sequence&lt;N&gt;&gt;
struct test {};

template &lt;std::size_t N, std::size_t... indices&gt;
struct test&lt;N, std::index_sequence&lt;indices...&gt;&gt; {
    std::array&lt;int, N&gt; arr{ };
    std::array&lt;std::atomic&lt;int*&gt;, N&gt; a{{&amp;arr[indices]}...};
};
</code></pre>
<p>wusste gar nicht, dass <code>{…}</code> ein gültiges pattern ist. Falls du noch nicht mit C++14 arbeiten kannst, lässt sich <code>make_index_sequence</code> auch leicht selbst implementieren.</p>
<p>PS: Explizite instantiierungen gehen auch direkter:</p>
<pre><code>template struct test&lt;5&gt;;
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2458527</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2458527</guid><dc:creator><![CDATA[Columbo]]></dc:creator><pubDate>Thu, 02 Jul 2015 11:50:32 GMT</pubDate></item><item><title><![CDATA[Reply to Array-Member initialisieren on Thu, 02 Jul 2015 12:26:16 GMT]]></title><description><![CDATA[<p>Arcoth schrieb:</p>
<blockquote>
<p>Huch, da fällt mir was viel hübscheres ein:</p>
</blockquote>
<p>In der Tat, <code>index_sequence</code> kannte ich noch garnicht, bzw. habe es selbst gebastelt.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2458534</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2458534</guid><dc:creator><![CDATA[Jodocus]]></dc:creator><pubDate>Thu, 02 Jul 2015 12:26:16 GMT</pubDate></item><item><title><![CDATA[Reply to Array-Member initialisieren on Thu, 02 Jul 2015 12:48:38 GMT]]></title><description><![CDATA[<p>Hm, zu früh gefreut, es kompiliert nicht:</p>
<pre><code class="language-cpp">#include &lt;array&gt;
#include &lt;atomic&gt;
#include &lt;utility&gt;

template &lt;std::size_t N, typename = std::make_index_sequence&lt;N&gt;&gt;
struct test {};

template &lt;std::size_t N, std::size_t... indices&gt;
struct test&lt;N, std::index_sequence&lt;indices...&gt;&gt; {
	std::array&lt;int, N&gt; arr{ };
	std::array&lt;std::atomic&lt;int*&gt;, N&gt; a{ { &amp;arr[indices] }... };
};

int main() {
	test&lt;5&gt; t;
}
</code></pre>
<p>Jedenfalls beschweren sich Clang und GCC, VS nimmt es, aber sicher nicht standardkonform. Ich muss also trotzdem mein Array von oben benutzen, also:</p>
<pre><code class="language-cpp">#include &lt;array&gt;
#include &lt;atomic&gt;
#include &lt;utility&gt;

template &lt;std::size_t N, typename = std::make_index_sequence&lt;N&gt;&gt;
struct test {};

template &lt;typename T, std::size_t N&gt;
struct atomic_array : public std::array&lt;std::atomic&lt;T&gt;, N&gt; {
	atomic_array(std::initializer_list&lt;T&gt; list) {
		auto iter = std::begin(*this);
		for(auto&amp; elem : list)
			*iter++ = std::move(elem);
	}
};

template &lt;std::size_t N, std::size_t... indices&gt;
struct test&lt;N, std::index_sequence&lt;indices...&gt;&gt; {
	std::array&lt;int, N&gt; arr{ };
	atomic_array&lt;int*, N&gt; a{ { &amp;arr[indices] }... };
};

int main() {
	test&lt;5&gt; t;
}
</code></pre>
<p>So geht es (endlich)!</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2458539</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2458539</guid><dc:creator><![CDATA[Jodocus]]></dc:creator><pubDate>Thu, 02 Jul 2015 12:48:38 GMT</pubDate></item><item><title><![CDATA[Reply to Array-Member initialisieren on Thu, 02 Jul 2015 13:00:53 GMT]]></title><description><![CDATA[<p>Edit: Alles Quatsch. Habe lediglich einen Flüchtigkeitsfehler eingebaut <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f921.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--clown_face"
      title=":clown:"
      alt="🤡"
    /><br />
So funktionierts:</p>
<pre><code>std::array&lt;std::atomic&lt;int*&gt;, N&gt; a {{ { &amp;arr[indices] }... }};
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2458543</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2458543</guid><dc:creator><![CDATA[Columbo]]></dc:creator><pubDate>Thu, 02 Jul 2015 13:00:53 GMT</pubDate></item><item><title><![CDATA[Reply to Array-Member initialisieren on Thu, 02 Jul 2015 13:25:05 GMT]]></title><description><![CDATA[<p>Warum kann ich <code>std::array&lt;std::atomic&lt;int*&gt;, N&gt;</code> mit einer <code>std::initializer_list&lt;std::initializer_list&lt;int*&gt;&gt;</code> initialisieren?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2458544</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2458544</guid><dc:creator><![CDATA[Jodocus]]></dc:creator><pubDate>Thu, 02 Jul 2015 13:25:05 GMT</pubDate></item><item><title><![CDATA[Reply to Array-Member initialisieren on Thu, 02 Jul 2015 13:31:41 GMT]]></title><description><![CDATA[<p>Jodocus schrieb:</p>
<blockquote>
<p>Warum kann ich <code>std::array&lt;std::atomic&lt;int*&gt;, N&gt;</code> mit einer <code>std::initializer_list&lt;std::initializer_list&lt;int*&gt;&gt;</code> initialisieren?</p>
</blockquote>
<p>Weil kein entsprechender Konstruktor vorhanden ist? Du kannst lediglich Klassen mit einem <code>initializer_list&lt;&gt;</code> Objekt initialisieren wenn ein entsprechender Konstruktor vorhanden ist. Aggregate haben keine vom User bereitgestellten Konstruktoren. Was in meinem (jetzt endlich) korrigierten Code verwendet wird, verwendet <code>initializer_list</code> gar nicht.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2458545</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2458545</guid><dc:creator><![CDATA[Columbo]]></dc:creator><pubDate>Thu, 02 Jul 2015 13:31:41 GMT</pubDate></item><item><title><![CDATA[Reply to Array-Member initialisieren on Thu, 02 Jul 2015 13:39:01 GMT]]></title><description><![CDATA[<p>Ich hab gefragt, warum ich es <strong>kann</strong>, da ich deinen Code so interpretiere (und eben array keinen solchen Konstruktor hat). Und da sind keine Initializer_lists drin? Was ist dann der Unterschied zwischen</p>
<pre><code class="language-cpp">std::array&lt;std::atomic&lt;int*&gt;, N&gt; a{ &amp;arr[indices]... };
</code></pre>
<pre><code class="language-cpp">std::array&lt;std::atomic&lt;int*&gt;, N&gt; a{{ &amp;arr[indices]... }};
</code></pre>
<p>und</p>
<pre><code class="language-cpp">std::array&lt;std::atomic&lt;int*&gt;, N&gt; a{{ { &amp;arr[indices] }... }};
</code></pre>
<p>?<br />
Das erste ist die normale Aggregat-Initialisierung. Das zweite ist eine Aggregat-Initialisierung eines temporären Arrays, das dann kopiert wird? Und das dritte?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2458547</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2458547</guid><dc:creator><![CDATA[Jodocus]]></dc:creator><pubDate>Thu, 02 Jul 2015 13:39:01 GMT</pubDate></item><item><title><![CDATA[Reply to Array-Member initialisieren on Thu, 02 Jul 2015 13:54:34 GMT]]></title><description><![CDATA[<pre><code>std::array&lt;std::atomic&lt;int*&gt;, N&gt; a{ &amp;arr[indices]... };
</code></pre>
<p>initialisiert jedes Element <code>e</code> <sub>n</sub> via</p>
<pre><code>std::atomic&lt;int*&gt; e_n = &amp;arr[n];
</code></pre>
<p>Diese Form der initialisierung von <code>a</code> ist tatsächlich equivalent zu<sup>1</sup></p>
<pre><code>std::array&lt;std::atomic&lt;int*&gt;, N&gt; a{{ &amp;arr[indices]... }};
</code></pre>
<p>Jedoch können die Klammern in diesem Fall weggelassen werden. In keinem der beiden Fälle wird ein temporäres Array oder <code>array</code> erstellt. Es werden lediglich Temporaries durch copy-initialization benötigt. Dir ist sicherlich bekannt, dass auch in</p>
<pre><code>std::string s = &quot;abc&quot;;
</code></pre>
<p>eine Temporary erstellt wird?</p>
<p>Der Große Unterschied der nun in der dritten Variante ausgenutzt wird, ist dass</p>
<pre><code>std::array&lt;std::atomic&lt;int*&gt;, N&gt; a{{ { &amp;arr[indices] }... }};
</code></pre>
<p>Eine Initialisierung a la</p>
<pre><code>std::atomic&lt;int*&gt; e_n = {&amp;arr[n]};
</code></pre>
<p>impliziert - aber hier brauchen wir - dank der Regeln von list-initialization - <strong>keine Temporary</strong>, denn der Konstruktor von <code>e</code> <sub>n</sub> wird direkt mit <code>&amp;arr[n]</code> aufgerufen.</p>
<p>Wenn wir jedoch</p>
<pre><code>std::array&lt;std::atomic&lt;int*&gt;, N&gt; a{ { &amp;arr[indices] }... };
</code></pre>
<p>schreiben, dann wird zuallererst versucht, dass interne Array mit <code>{ &amp;arr[0] }</code> zu initialisieren, was natürlich fehlschlägt.<br />
---<br />
<sup>1</sup> Ich bin mir gerade nicht einmal sicher, ob die erste Variante standardkonform ist, da §8.5.1/11 was anderes suggeriert, aber da alle mir bekannten Implementierungen es per se annehmen, scheine ich da etwas falsch zu interpretieren</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2458548</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2458548</guid><dc:creator><![CDATA[Columbo]]></dc:creator><pubDate>Thu, 02 Jul 2015 13:54:34 GMT</pubDate></item><item><title><![CDATA[Reply to Array-Member initialisieren on Thu, 02 Jul 2015 14:00:17 GMT]]></title><description><![CDATA[<p>Arcoth schrieb:</p>
<blockquote>
<p>Eine Initialisierung a la</p>
<pre><code>std::atomic&lt;int*&gt; e_n = {&amp;arr[n]};
</code></pre>
<p>impliziert - aber hier brauchen wir - dank der Regeln von list-initialization - <strong>keine Temporary</strong>, denn der Konstruktor von <code>e</code> <sub>n</sub> wird direkt mit <code>&amp;arr[n]</code> aufgerufen.</p>
</blockquote>
<p>Meinst du nicht eher, dass das</p>
<pre><code>std::atomic&lt;int*&gt; e_n{&amp;arr[n]}; // ohne =
</code></pre>
<p>impliziert? Gemäß <a href="http://en.cppreference.com/w/cpp/language/list_initialization" rel="nofollow">http://en.cppreference.com/w/cpp/language/list_initialization</a> wäre das mit dem <code>=</code> eine copy-list initialization und nicht direct.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2458550</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2458550</guid><dc:creator><![CDATA[Jodocus]]></dc:creator><pubDate>Thu, 02 Jul 2015 14:00:17 GMT</pubDate></item><item><title><![CDATA[Reply to Array-Member initialisieren on Thu, 02 Jul 2015 14:08:01 GMT]]></title><description><![CDATA[<p>Beide. In jeder Form von list-initialization werden die initializer-clauses stets direkt an den Konstruktor weitergeleitet - außer ein <code>initializer_list</code> Konstruktor wird aufgerufen, was hier aber offensichtlich nicht der Fall ist.</p>
<p>Edit: Was genau meinste gerade? Bin etwas verwirrt. Dass die Arrayelemente bei Aggregatinitialisierung stets mittels copy-initialization initialisiert werden, habe ich bereits aufgezeigt.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2458551</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2458551</guid><dc:creator><![CDATA[Columbo]]></dc:creator><pubDate>Thu, 02 Jul 2015 14:08:01 GMT</pubDate></item><item><title><![CDATA[Reply to Array-Member initialisieren on Fri, 03 Jul 2015 11:06:45 GMT]]></title><description><![CDATA[<p>Arcoth schrieb:</p>
<blockquote>
<p>Bin etwas verwirrt.</p>
</blockquote>
<p>Hat sich erledigt, ich hab mir die Regeln im Standard noch mal durchgelesen. Danke!</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2458604</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2458604</guid><dc:creator><![CDATA[Jodocus]]></dc:creator><pubDate>Fri, 03 Jul 2015 11:06:45 GMT</pubDate></item><item><title><![CDATA[Reply to Array-Member initialisieren on Fri, 03 Jul 2015 11:45:49 GMT]]></title><description><![CDATA[<p>Hab' auch mein vorhin erwähntes Problem gelöst:</p>
<blockquote>
<p><sup>1</sup> Ich bin mir gerade nicht einmal sicher, ob die erste Variante standardkonform ist, da §8.5.1/11 was anderes suggeriert, aber da alle mir bekannten Implementierungen es per se annehmen, scheine ich da etwas falsch zu interpretieren</p>
</blockquote>
<p>Dieser Paragraph wurde durch <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1270" rel="nofollow">CWG #1270</a> angepasst, sodass</p>
<pre><code>std::array&lt;int, 1&gt; arr{0};
</code></pre>
<p>seit C++14 gültig ist.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2458608</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2458608</guid><dc:creator><![CDATA[Columbo]]></dc:creator><pubDate>Fri, 03 Jul 2015 11:45:49 GMT</pubDate></item><item><title><![CDATA[Reply to Array-Member initialisieren on Sat, 04 Jul 2015 06:53:23 GMT]]></title><description><![CDATA[<p>Arcoth schrieb:</p>
<blockquote>
<p>Edit: Was genau meinste gerade? Bin etwas verwirrt. Dass die Arrayelemente bei Aggregatinitialisierung stets mittels copy-initialization initialisiert werden, habe ich bereits aufgezeigt.</p>
</blockquote>
<p>Was ich meinte, ist, dass eine List-Initialization à la</p>
<pre><code>std::atomic&lt;int*&gt; e_n = {&amp;arr[n]};
</code></pre>
<p>Auch ein Temporary erzeugt, im Gegensatz zu</p>
<pre><code class="language-cpp">std::atomic&lt;int*&gt; e_n{&amp;arr[n]};
</code></pre>
<p>, wobei letzteres wohl bei</p>
<pre><code class="language-cpp">std::array&lt;std::atomic&lt;int*&gt;, N&gt; a{{ { &amp;arr[indices] }... }};
</code></pre>
<p>passiert.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2458667</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2458667</guid><dc:creator><![CDATA[Jodocus]]></dc:creator><pubDate>Sat, 04 Jul 2015 06:53:23 GMT</pubDate></item></channel></rss>