<?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[Vector verändern während iteration]]></title><description><![CDATA[<p>Ich habe mir mal eine Klasse gebaut die es erlaubt während des iterierens eines Vectors Elemente zu löschen/hinzuzufügen ohne, dass sich der iterator/size etc ändert und der compiler fehler ausspuckt.<br />
Gibt es in STL elegantere lösungen wie man sowas hinbekommt?<br />
Oder muss man jedes mal überlegen, in einer for-schleife, wenn man zb. ein element löscht bei welcher position man weiter macht um zum nächsten element zu gelangen?<br />
Oder doch eine klasse wie diese?</p>
<p>Das ist die klasse, ist aber noch nicht vollständig.</p>
<pre><code class="language-cpp">#ifndef LOCKABLEVECTOR_HPP
#define LOCKABLEVECTOR_HPP
#include &lt;vector&gt;
#include &lt;iostream&gt;

template &lt;typename T&gt;
struct LockableVector
{
	void add(const T &amp;value);
	void remove(int index);
	void lock();
	void unlock();

	const std::vector&lt;T&gt;&amp; get_items();

	private:
	std::vector&lt;T&gt; added_new{};
	std::vector&lt;T&gt; items{};
	std::vector&lt;int&gt; items_validity{};

	bool is_modified{false};
	bool is_finished{true};

	void merge();
};

template &lt;typename T&gt;
void LockableVector&lt;T&gt;::add(const T &amp;value)
{
	if (is_finished)
	{
		items.push_back(value);
		items_validity.push_back(1);
	}
	else
	{
		added_new.push_back(value);
		is_modified = true;
	}
}

template &lt;typename T&gt;
void LockableVector&lt;T&gt;::remove(int index)
{
	if (is_finished)
	{
		items.erase(items.begin() + index);
		items_validity.erase(items_validity.begin() + index);
	}
	else
	{
		items_validity.at(index) = 0;
		is_modified = true;
	}
}

template &lt;typename T&gt;
void LockableVector&lt;T&gt;::lock()
{
	if (!is_finished)
	{
		std::cout &lt;&lt; &quot;already locked&quot;;
		return;
	}
	is_finished = false;
}

template &lt;typename T&gt;
void LockableVector&lt;T&gt;::unlock()
{
	if (is_finished)
		return;
	merge();
	is_finished = true;
}

template &lt;typename T&gt;
const std::vector&lt;T&gt;&amp; LockableVector&lt;T&gt;::get_items() { return items; }

template &lt;typename T&gt;
void LockableVector&lt;T&gt;::merge()
{
	if (is_modified)
	{
		const auto size = items.size() - 1;
		for (auto i = size; i &gt; 0; --i)
			if (items_validity.at(i) == 0)
			{
				items.erase(items.begin() + i);
				items_validity.erase(items_validity.begin() + i);
			}
		for (auto &amp;item : added_new)
		{
			items.push_back(item);
			items_validity.push_back(1);
		}
		added_new.clear();
		is_modified = false;
	}
}
#endif 
</code></pre>
<p><em><strong>added_new</strong></em> wird benutzt beim hinzufügen von elementen<br />
<em><strong>items</strong></em> sind die elemente<br />
<em><strong>items_validity</strong></em> wird beim deleten benutzt und besteht aus 0 und 1 (alle positionen mit 0 werden dann nach der iteration gelöscht)</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/348861/vector-verändern-während-iteration</link><generator>RSS for Node</generator><lastBuildDate>Sun, 19 Apr 2026 21:25:08 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/348861.rss" rel="self" type="application/rss+xml"/><pubDate>Sat, 26 Jan 2019 19:03:51 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Vector verändern während iteration on Sat, 26 Jan 2019 19:03:51 GMT]]></title><description><![CDATA[<p>Ich habe mir mal eine Klasse gebaut die es erlaubt während des iterierens eines Vectors Elemente zu löschen/hinzuzufügen ohne, dass sich der iterator/size etc ändert und der compiler fehler ausspuckt.<br />
Gibt es in STL elegantere lösungen wie man sowas hinbekommt?<br />
Oder muss man jedes mal überlegen, in einer for-schleife, wenn man zb. ein element löscht bei welcher position man weiter macht um zum nächsten element zu gelangen?<br />
Oder doch eine klasse wie diese?</p>
<p>Das ist die klasse, ist aber noch nicht vollständig.</p>
<pre><code class="language-cpp">#ifndef LOCKABLEVECTOR_HPP
#define LOCKABLEVECTOR_HPP
#include &lt;vector&gt;
#include &lt;iostream&gt;

template &lt;typename T&gt;
struct LockableVector
{
	void add(const T &amp;value);
	void remove(int index);
	void lock();
	void unlock();

	const std::vector&lt;T&gt;&amp; get_items();

	private:
	std::vector&lt;T&gt; added_new{};
	std::vector&lt;T&gt; items{};
	std::vector&lt;int&gt; items_validity{};

	bool is_modified{false};
	bool is_finished{true};

	void merge();
};

template &lt;typename T&gt;
void LockableVector&lt;T&gt;::add(const T &amp;value)
{
	if (is_finished)
	{
		items.push_back(value);
		items_validity.push_back(1);
	}
	else
	{
		added_new.push_back(value);
		is_modified = true;
	}
}

template &lt;typename T&gt;
void LockableVector&lt;T&gt;::remove(int index)
{
	if (is_finished)
	{
		items.erase(items.begin() + index);
		items_validity.erase(items_validity.begin() + index);
	}
	else
	{
		items_validity.at(index) = 0;
		is_modified = true;
	}
}

template &lt;typename T&gt;
void LockableVector&lt;T&gt;::lock()
{
	if (!is_finished)
	{
		std::cout &lt;&lt; &quot;already locked&quot;;
		return;
	}
	is_finished = false;
}

template &lt;typename T&gt;
void LockableVector&lt;T&gt;::unlock()
{
	if (is_finished)
		return;
	merge();
	is_finished = true;
}

template &lt;typename T&gt;
const std::vector&lt;T&gt;&amp; LockableVector&lt;T&gt;::get_items() { return items; }

template &lt;typename T&gt;
void LockableVector&lt;T&gt;::merge()
{
	if (is_modified)
	{
		const auto size = items.size() - 1;
		for (auto i = size; i &gt; 0; --i)
			if (items_validity.at(i) == 0)
			{
				items.erase(items.begin() + i);
				items_validity.erase(items_validity.begin() + i);
			}
		for (auto &amp;item : added_new)
		{
			items.push_back(item);
			items_validity.push_back(1);
		}
		added_new.clear();
		is_modified = false;
	}
}
#endif 
</code></pre>
<p><em><strong>added_new</strong></em> wird benutzt beim hinzufügen von elementen<br />
<em><strong>items</strong></em> sind die elemente<br />
<em><strong>items_validity</strong></em> wird beim deleten benutzt und besteht aus 0 und 1 (alle positionen mit 0 werden dann nach der iteration gelöscht)</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2569224</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2569224</guid><dc:creator><![CDATA[[[global:former_user]]]]></dc:creator><pubDate>Sat, 26 Jan 2019 19:03:51 GMT</pubDate></item><item><title><![CDATA[Reply to Vector verändern während iteration on Sat, 26 Jan 2019 19:28:36 GMT]]></title><description><![CDATA[<p>Ich halte das für keine gute Idee. Das kostet sehr viel Performance. Warum ist es dir so wichtig, dass der Iterator stabil bleibt? Vielleicht solltest du dir eine andere Lösung überlegen, oder eine andere Datenstruktur nehmen?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2569225</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2569225</guid><dc:creator><![CDATA[Mechanics]]></dc:creator><pubDate>Sat, 26 Jan 2019 19:28:36 GMT</pubDate></item><item><title><![CDATA[Reply to Vector verändern während iteration on Sat, 26 Jan 2019 19:36:01 GMT]]></title><description><![CDATA[<p>Zu &quot;löschendes&quot; Element mit einem Element vom Ende des Vectors swappen und <code>--new_end</code> dann nach der Schleife erase?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2569226</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2569226</guid><dc:creator><![CDATA[Swordfish]]></dc:creator><pubDate>Sat, 26 Jan 2019 19:36:01 GMT</pubDate></item><item><title><![CDATA[Reply to Vector verändern während iteration on Sat, 26 Jan 2019 21:02:55 GMT]]></title><description><![CDATA[<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/28374">@Mechanics</a> sagte in <a href="/forum/post/2569225">Vector verändern während iteration</a>:</p>
<blockquote>
<p>Warum ist es dir so wichtig, dass der Iterator stabil bleibt?</p>
</blockquote>
<p>Na weil wenn der iterator nicht stabil bleibt während ich den vector verändere dann bekommt man n error weil entweder der iterator größer wird(add) oder kleiner(delete)</p>
<pre><code class="language-cpp">	std::vector&lt;int&gt; v{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};

	for (auto i = v.begin(); i != v.end(); ++i)
	{
		std::cout &lt;&lt; *i &lt;&lt; &quot; &quot;;
		if (*i == 1)
			v.erase(i); // Error, can't increment vector iterator past end
	}
</code></pre>
<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/28374">@Mechanics</a> sagte in <a href="/forum/post/2569225">Vector verändern während iteration</a>:</p>
<blockquote>
<p>oder eine andere Datenstruktur nehmen?</p>
</blockquote>
<p>Alle anderen datenstrukturen verhalten sich genauso oder nicht?</p>
<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/8250">@Swordfish</a> sagte in <a href="/forum/post/2569226">Vector verändern während iteration</a>:</p>
<blockquote>
<p>Zu &quot;löschendes&quot; Element mit einem Element vom Ende des Vectors swappen und --new_end dann nach der Schleife erase?</p>
</blockquote>
<p>Ja das würde funktionieren für delete, aber für adden? Müsste man dann quasi das neue element mit dem ersten swappen und ```cpp<br />
++new_end</p>
<pre><code class="language-machen,"></code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2569232</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2569232</guid><dc:creator><![CDATA[[[global:former_user]]]]></dc:creator><pubDate>Sat, 26 Jan 2019 21:02:55 GMT</pubDate></item><item><title><![CDATA[Reply to Vector verändern während iteration on Sat, 26 Jan 2019 21:19:26 GMT]]></title><description><![CDATA[<p>Erase gibt einen Iterator zurück, könnte man in dem Fall also ganz einfach lösen, mit 1-2 Zeilen mehr Code, statt eine sehr viel langsamere Datenstruktur aufzubauen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2569234</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2569234</guid><dc:creator><![CDATA[Mechanics]]></dc:creator><pubDate>Sat, 26 Jan 2019 21:19:26 GMT</pubDate></item><item><title><![CDATA[Reply to Vector verändern während iteration on Sat, 26 Jan 2019 21:56:04 GMT]]></title><description><![CDATA[<p>@Bengel sagte in <a href="/forum/post/2569232">Vector verändern während iteration</a>:</p>
<blockquote>
<p>Ja das würde funktionieren für delete, aber für adden? Müsste man dann quasi das neue element mit dem ersten swappen und <code>++new_end</code>?</p>
</blockquote>
<p>Mit <code>reserve()</code> vor der schleife dafür sorgen, daß keine reallokation passieren kann und <code>push_back()</code>/<code>emplace_back()</code>?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2569235</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2569235</guid><dc:creator><![CDATA[Swordfish]]></dc:creator><pubDate>Sat, 26 Jan 2019 21:56:04 GMT</pubDate></item><item><title><![CDATA[Reply to Vector verändern während iteration on Sun, 27 Jan 2019 18:42:52 GMT]]></title><description><![CDATA[<p>@Bengel sagte in <a href="/forum/post/2569224">Vector verändern während iteration</a>:</p>
<blockquote>
<p>Gibt es in STL elegantere lösungen wie man sowas hinbekommt?</p>
</blockquote>
<p>Also zum Löschen kannst du erase + std::remove_if nutzen:</p>
<pre><code>std::vector&lt;int&gt; v = {1, 2, 3, 4};
// alle geraden Zahlen loeschen
v.erase(std::remove_if(v.begin(), v.end(), [](int i){ return i%2 == 0; }), v.end());
</code></pre>
<p>Edit: oder um bei deinem Beisiel oben zu bleiben, wo du die 1en löscht:</p>
<pre><code>v.erase(std::remove(v.begin(), v.end(), 1), v.end());
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2569294</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2569294</guid><dc:creator><![CDATA[wob]]></dc:creator><pubDate>Sun, 27 Jan 2019 18:42:52 GMT</pubDate></item></channel></rss>