<?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[Daten laden und Move]]></title><description><![CDATA[<p>Hi,</p>
<p>ist das so eine gültige (kein UB o.ä.) und sinnvolle art, move zu benutzen (Zeilen 38-43)?</p>
<pre><code class="language-cpp">struct DataObject
{
	int classID_;
	VectorXd data_;
};

bool load(DataObject&amp; obj, int dim, std::istream&amp; is)
{
	is &gt;&gt; obj.classID_;
	obj.data_.resize(dim);
	for(int i = 0; i &lt; dim; ++i)
	{
		is &gt;&gt; obj.data_(i);
	}

	return is.good();
}

struct DataSet
{
	int numClasses_;
	int dim_;
	std::vector&lt;DataObject&gt; objs_;
};

DataSet load(const string&amp; fileName)
{
	DataSet data;

	ifstream ifs(fileName);
	if(!ifs)
	{
		log() &lt;&lt; &quot;failed to open file&quot; &lt;&lt; endl;
		onFatalError(); //stattdessen würde auch exception gehen
	}
	ifs &gt;&gt; data.numClasses_ &gt;&gt; data.dim_;

	DataObject obj;	
	while(load(obj, data.dim_, ifs))
	{
        ----&gt;   //Hier wird gemoved!! &lt;------
		data.objs_.push_back(move(obj));
	}

	log() &lt;&lt; &quot;successfully loaded &quot; &lt;&lt; fileName &lt;&lt; endl;
	return data;
}
</code></pre>
<p>Sinn ist es, das kopieren in den vektor zu vermeiden.<br />
Hat nach dem moven die variable auf dem stack noch einen &quot;gültigen&quot; Zustand?<br />
Im load weise ich danach direkt neue Werte zu, also sollte das eigentlich gehen.</p>
<p>Außerdem: Findet ihr das so ne gute art, daten zu laden? Ich wollte erst operator&gt;&gt; nehmen, aber leider brauche ich zum laden außerdem die dimension übergeben.</p>
<p>Und wie würdet ihr die Fehlerbehandlung machen? Im moment ist da das problem, dass die while(load(...)) Schleife sobald etwas falsches in der datei steht einfach abbricht. Das soll auch so sein, weil die datei ja irgendwann zuende ist. Wenn aber vor dem Ende der Datei schon falsche/unerwartete zeichen/daten auftreten, dann sollte das eigentlich anders behandelt werden.</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/316249/daten-laden-und-move</link><generator>RSS for Node</generator><lastBuildDate>Thu, 30 Jul 2026 03:39:49 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/316249.rss" rel="self" type="application/rss+xml"/><pubDate>Fri, 26 Apr 2013 16:11:57 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Daten laden und Move on Fri, 26 Apr 2013 16:17:32 GMT]]></title><description><![CDATA[<p>Hi,</p>
<p>ist das so eine gültige (kein UB o.ä.) und sinnvolle art, move zu benutzen (Zeilen 38-43)?</p>
<pre><code class="language-cpp">struct DataObject
{
	int classID_;
	VectorXd data_;
};

bool load(DataObject&amp; obj, int dim, std::istream&amp; is)
{
	is &gt;&gt; obj.classID_;
	obj.data_.resize(dim);
	for(int i = 0; i &lt; dim; ++i)
	{
		is &gt;&gt; obj.data_(i);
	}

	return is.good();
}

struct DataSet
{
	int numClasses_;
	int dim_;
	std::vector&lt;DataObject&gt; objs_;
};

DataSet load(const string&amp; fileName)
{
	DataSet data;

	ifstream ifs(fileName);
	if(!ifs)
	{
		log() &lt;&lt; &quot;failed to open file&quot; &lt;&lt; endl;
		onFatalError(); //stattdessen würde auch exception gehen
	}
	ifs &gt;&gt; data.numClasses_ &gt;&gt; data.dim_;

	DataObject obj;	
	while(load(obj, data.dim_, ifs))
	{
        ----&gt;   //Hier wird gemoved!! &lt;------
		data.objs_.push_back(move(obj));
	}

	log() &lt;&lt; &quot;successfully loaded &quot; &lt;&lt; fileName &lt;&lt; endl;
	return data;
}
</code></pre>
<p>Sinn ist es, das kopieren in den vektor zu vermeiden.<br />
Hat nach dem moven die variable auf dem stack noch einen &quot;gültigen&quot; Zustand?<br />
Im load weise ich danach direkt neue Werte zu, also sollte das eigentlich gehen.</p>
<p>Außerdem: Findet ihr das so ne gute art, daten zu laden? Ich wollte erst operator&gt;&gt; nehmen, aber leider brauche ich zum laden außerdem die dimension übergeben.</p>
<p>Und wie würdet ihr die Fehlerbehandlung machen? Im moment ist da das problem, dass die while(load(...)) Schleife sobald etwas falsches in der datei steht einfach abbricht. Das soll auch so sein, weil die datei ja irgendwann zuende ist. Wenn aber vor dem Ende der Datei schon falsche/unerwartete zeichen/daten auftreten, dann sollte das eigentlich anders behandelt werden.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2318781</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2318781</guid><dc:creator><![CDATA[*Q* 1]]></dc:creator><pubDate>Fri, 26 Apr 2013 16:17:32 GMT</pubDate></item><item><title><![CDATA[Reply to Daten laden und Move on Fri, 26 Apr 2013 17:13:08 GMT]]></title><description><![CDATA[<p>Ja, Du darfst in diesem Fall moven.<br />
Ich würde die Daten binär schreiben.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2318803</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2318803</guid><dc:creator><![CDATA[PaulaAusmKnast]]></dc:creator><pubDate>Fri, 26 Apr 2013 17:13:08 GMT</pubDate></item><item><title><![CDATA[Reply to Daten laden und Move on Fri, 26 Apr 2013 17:16:00 GMT]]></title><description><![CDATA[<p>...und die Daten schlussendlich binär wieder auslesen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2318804</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2318804</guid><dc:creator><![CDATA[PaulaAusmKnast]]></dc:creator><pubDate>Fri, 26 Apr 2013 17:16:00 GMT</pubDate></item><item><title><![CDATA[Reply to Daten laden und Move on Fri, 26 Apr 2013 18:25:22 GMT]]></title><description><![CDATA[<p>Q schrieb:</p>
<blockquote>
<p>ist das so eine gültige (kein UB o.ä.) und sinnvolle art, move zu benutzen (Zeilen 38-43)?</p>
</blockquote>
<p>Der Code ist gültig, aber auf eine ungewollte Weise. Es gibt nämlich keinen Default-Movekonstruktor, das übernimmt der Kopierkonstruktor. Alle Member rüberzumoven geht nämlich nicht, stell dir vor, ein unique_ptr würde das machen (den Pointer rübermoven=rüberkopieren).</p>
<p>Deshalb musst dir deinen eigenen Movekonstruktor schreiben.</p>
<p>Aber dann hast du UB.<br />
Alles, was du mit einem moved-from-Objekt machen darfst, ist ihm es erneut etwas zuweisen oder den Destruktor aufzurufen. resize auf einen gemovten Vektor =&gt; UB</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2318818</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2318818</guid><dc:creator><![CDATA[scarymovie]]></dc:creator><pubDate>Fri, 26 Apr 2013 18:25:22 GMT</pubDate></item><item><title><![CDATA[Reply to Daten laden und Move on Fri, 26 Apr 2013 18:41:02 GMT]]></title><description><![CDATA[<p>Q schrieb:</p>
<blockquote>
<p>Außerdem: Findet ihr das so ne gute art, daten zu laden? Ich wollte erst operator&gt;&gt; nehmen, aber leider brauche ich zum laden außerdem die dimension übergeben.</p>
</blockquote>
<p>Das ist so in Ordnung. <code>std::getline</code> ist da ganz ähnlich aufgebaut.</p>
<p>Ich würde allerdings die Signatur etwas anpassen:</p>
<pre><code class="language-cpp">std::istream&amp; load(std::istream&amp; is, DataObject&amp; obj, std::size_t dim)
</code></pre>
<p>(eine alternative Implementation wäre</p>
<pre><code class="language-cpp">is &gt;&gt; obj.classID_;
obj.data_.reserve(dim);
std::copy_n(std::istream_iterator&lt;int&gt;(is), dim, std::back_inserter(obj.data_));
if (!is) is.setstate(std::ios::failbit);
return is;
</code></pre>
<p>)</p>
<p>Q schrieb:</p>
<blockquote>
<p>Und wie würdet ihr die Fehlerbehandlung machen? Im moment ist da das problem, dass die while(load(...)) Schleife sobald etwas falsches in der datei steht einfach abbricht. Das soll auch so sein, weil die datei ja irgendwann zuende ist. Wenn aber vor dem Ende der Datei schon falsche/unerwartete zeichen/daten auftreten, dann sollte das eigentlich anders behandelt werden.</p>
</blockquote>
<p>Diese Unterscheidung hast du bereits (wenn du Zeile 4 so übernimmst). Bei is.fail() trat ein Fehler auf, bei is.eof() ist alles in Butter.</p>
<p>PaulaAusmKnast schrieb:</p>
<blockquote>
<p>Ich würde die Daten binär schreiben.</p>
</blockquote>
<p>Besser nicht, damit handelt man sich nur Inkompatibilitäten ein.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2318821</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2318821</guid><dc:creator><![CDATA[scarymovie]]></dc:creator><pubDate>Fri, 26 Apr 2013 18:41:02 GMT</pubDate></item><item><title><![CDATA[Reply to Daten laden und Move on Sat, 27 Apr 2013 08:27:05 GMT]]></title><description><![CDATA[<p>(etwas von mir gekürzt)</p>
<p>Q schrieb:</p>
<blockquote>
<p>ist das so eine gültige [...] und sinnvolle art, move zu benutzen [...]?</p>
<pre><code class="language-cpp">struct DataObject
{
	int classID_;
	VectorXd data_;
};

bool load(DataObject&amp; obj, int dim, std::istream&amp; is)
// ...
;

std::vector&lt;DataObject&gt; load(const string&amp; fileName)
{
	std::vector&lt;DataObject&gt; data;

	ifstream ifs(fileName);
	if(!ifs)
	{
		log() &lt;&lt; &quot;failed to open file&quot; &lt;&lt; endl;
		onFatalError(); //stattdessen würde auch exception gehen
	}
	ifs &gt;&gt; data.numClasses_ &gt;&gt; data.dim_;
	
	DataObject obj;	
	while(load(obj, 42, ifs))
	{
                //Hier wird gemoved!!
		data.push_back(move(obj));
	}

	log() &lt;&lt; &quot;successfully loaded &quot; &lt;&lt; fileName &lt;&lt; endl;
	return data;
}
</code></pre>
</blockquote>
<p>Ja, das ist in Ordnung so. Allerdings musst du Dich fragen, ob DataObjekt überhaupt einen Move-Konstruktor hat; denn wenn nicht, bringt dir <code>move(...)</code> hier nichts. <code>move(...)</code> ist ja nur eine Möglichkeit, dem Compiler zu sagen, dass man doch lieber den Rvalue-Overload nehmen will. Den gibt es zwar, also <code>push_back(DataObject&amp;&amp;)</code> , aber der kann nicht viel anders machen, als das Objekt doch nur zu kopieren, wenn DataObject keinen Move-Konstruktor hat.</p>
<p>Laut C++ Standard wird der Compiler in bestimmten Situationen automatische einen Move-Konstruktor erzeugen, der eben elementweise &quot;movet&quot;. Ob das hier der Fall ist, hängt glaub'ich davon ab, was VectorXd für ein Typ ist. Außerdem ist diese Automatik noch nicht überall verfügbar. Meines Wissens nach kann der Compiler von Microsoft noch keinen Move-Constructor automatisch erzeugen.</p>
<p>Q schrieb:</p>
<blockquote>
<p>Hat nach dem moven die variable auf dem stack noch einen &quot;gültigen&quot; Zustand?</p>
</blockquote>
<p>Kommt drauf an. Hat DataObjekt einen Move-Konstruktor? Hat VectorXd einen Move-Konstruktor? Wenn ja, was macht der? Wenn du einen VectorXd, von dem &quot;gemovet&quot; wurde, in <code>load</code> problemlos befüllen kannst, dann sehe ich da kein Problem. Wie gesagt, &quot;Moven&quot; ist keine Compiler-Magie. Da wird auch nur das ausgeführt, was Klassenautoren per Move-Konstruktor definiert haben. In jedem Fall sollte ein &quot;moved-from-Objekt&quot; normal zerstörbar sein; denn der Destruktor von obj wird hier immer am Ende der Funktion ausgeführt, wie es sich für ein Objekt im automatischen Speicher gehört. Und falls ein Objekttyp &quot;Movable&quot; und &quot;Assignable&quot; ist, sollte es auch in einem &quot;moved-from&quot;-Zustand zuweisbar sein. Das ist jetzt kein Muss, aber es ist das, was ich erwarten würde und auch das, was die Standardbibliothek erwartet. Darüberhinaus kannst du natürlich für eigene Typen eigene Garantien machen oder sein lassen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2318918</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2318918</guid><dc:creator><![CDATA[krümelkacker]]></dc:creator><pubDate>Sat, 27 Apr 2013 08:27:05 GMT</pubDate></item><item><title><![CDATA[Reply to Daten laden und Move on Sat, 27 Apr 2013 08:37:56 GMT]]></title><description><![CDATA[<blockquote>
<p>stell dir vor, ein unique_ptr würde das machen (den Pointer rübermoven=rüberkopieren).</p>
</blockquote>
<p>Nicht sicher was du meinst. Machen nicht Move-Ctor/Move-Assignment-Op von <code>unique_ptr</code> genau das?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2318919</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2318919</guid><dc:creator><![CDATA[Sone]]></dc:creator><pubDate>Sat, 27 Apr 2013 08:37:56 GMT</pubDate></item><item><title><![CDATA[Reply to Daten laden und Move on Sat, 27 Apr 2013 13:03:44 GMT]]></title><description><![CDATA[<p>scarymovie schrieb:</p>
<blockquote>
<p>Alles, was du mit einem moved-from-Objekt machen darfst, ist ihm es erneut etwas zuweisen oder den Destruktor aufzurufen.</p>
</blockquote>
<p>Es hält keinen davon ab, eine Klasse zu schreiben, deren Objekte im &quot;moved-from&quot;-Zustand mehr können als nur das.</p>
<p>scarymovie schrieb:</p>
<blockquote>
<p>resize auf einen gemovten Vektor =&gt; UB</p>
</blockquote>
<p>Kannst du das bitte näher begründen? Danke.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2319009</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2319009</guid><dc:creator><![CDATA[krümelkacker]]></dc:creator><pubDate>Sat, 27 Apr 2013 13:03:44 GMT</pubDate></item><item><title><![CDATA[Reply to Daten laden und Move on Sat, 27 Apr 2013 13:21:09 GMT]]></title><description><![CDATA[<blockquote>
<p>resize auf einen gemovten Vektor =&gt; UB</p>
</blockquote>
<p>Ähm... sofern du <code>std::vector</code> meinst: nein. Der Allokator wird (solange das Allocator-Template-Argument <code>std::allocator</code> ist) kopiert und die Elemente werden geswapped.<br />
Edit: Naja, so implementiert es zumindest der GCC. <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="🤡"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/2319013</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2319013</guid><dc:creator><![CDATA[Sone]]></dc:creator><pubDate>Sat, 27 Apr 2013 13:21:09 GMT</pubDate></item><item><title><![CDATA[Reply to Daten laden und Move on Sat, 27 Apr 2013 13:57:16 GMT]]></title><description><![CDATA[<p>Ich glaube auch nicht, dass scarymovie da Recht hat. Der &quot;moved-from&quot; Zustand von Bibliothekstypen ist laut 17.6.5.15 &quot;valud but unspecified&quot;. Und da es für vector&lt;&gt;::resize keine precondition gibt, sehe ich keinen Grund, warum resize zu UB führen sollte. Desweiteren wird verlangt, dass das Moven von StdLib-Containern mit Ausnahme von std::array&lt;&gt; in konstanter Zeit zu passieren hat. Was für ein valider Zustand kann das denn dann noch sein im Falle von vector&lt;&gt; außer der eines leeren Vektors? Ich find's aber schade, dass das explizit nirgens steht (oder ich es wenigstens nicht gefunden habe).</p>
<p>Die Move-Zuweisung von unique_ptr's</p>
<pre><code>up = move(up2);
</code></pre>
<p>ist zumindest äquivalent zu</p>
<pre><code>up.reset(up2.release());
</code></pre>
<p>definiert worden. Und damit ist klar, in welchen Zustand sich <code>up2</code> danach befinden sollte.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2319024</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2319024</guid><dc:creator><![CDATA[krümelkacker]]></dc:creator><pubDate>Sat, 27 Apr 2013 13:57:16 GMT</pubDate></item></channel></rss>