<?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[Erster C++-Gehversuch, Feedback erwünscht]]></title><description><![CDATA[<p>Hallo Forum,</p>
<p>ich komme ursprünglich aus der Java-Welt und mach grad mal meine ersten Gehversuche mit C++11.</p>
<p>Als &quot;Übungsprojekt&quot; habe ich mich jetzt einfach mal für einen Löser für Magische Quadrate beliebiger Größe entschieden:</p>
<p>- Es macht Sinn, das ganze auf Performance zu trimmen<br />
- Es beinhaltet ein paar grundlegende Templates<br />
- Später kann man darauf aufbauend sich schön mit Parallelisierung auseinandersetzen, denke ich.</p>
<p>Wie gesagt, das ganze ist ein erster Gehversuch und ich würde mich einfach gerne über ein bisschen Feedback freuen ob das ganze in die richtige Richtung geht. Zielplattform ist Linux und gcc. Interessiert bin ich nicht nur an &quot;echte&quot; Fehler sondern auch an Meinungen ob etwas &quot;Stilunüblich&quot; in der C++-Welt ist.</p>
<p>Gelöst wird das ganze folgendermaßen: Es wird rekursiv durch alle möglichen Kombinationen iteriert, also das nächste freie Feld einmal mit allen verbleibenden Zahlen gefüllt und dafür dann wieder die Funktion aufgerufen wird. Dabei wird aus einer &quot;Verzweigung&quot; ausgestiegen, sobald sich das Quadrat bei einer Prüfung als unlösbar herausstellt. Die methode bekommt einen Consumer als Funktionspointer, jedes gefundene fertige Quadrat wird an diesen Consumer zurückgegeben.</p>
<p>Also hier der Code:</p>
<pre><code>#pragma once

#include &lt;cassert&gt;
#include &lt;array&gt;

template&lt;int Size&gt;
class MagicSquare {
public:

	inline void unset_cell(int row, int col) {
		unset_cell(cell_id(row, col));
	}

	inline void set_cell(int row, int col, int val) {
		set_cell(cell_id(row, col), val);
	}

	inline int get_cell(int row, int col) {
		return get_cell(cell_id(row, col));
	}

	inline void replace_cell(int row, int col, int val) {
		replace_cell(cell_id(row, col), val);
	}

	int get_progress() {
		int prog = 0;
		for (int idx = 0; idx &lt; FIELDS; ++idx) {
			if (field[idx]) {
				++prog;
			}
		}
		return prog;
	}

	void resolve(void (*consumer)(MagicSquare&lt;Size&gt; &amp;)) {
		resolve(consumer, get_progress());
	}

	void resolve(void (*consumer)(MagicSquare&lt;Size&gt; &amp;), int progress) {
		if (progress == FIELDS) {
			consumer(*this);
		}

		int firstUnusedCell = 0;
		while (field[firstUnusedCell]) {
			++firstUnusedCell;
		}

		for (int idx = 1; idx &lt; FIELDS + 1; ++idx) {
			if (usedNumbers[idx]) {
				continue;
			}
			replace_cell(firstUnusedCell, idx);

			if (check_square()) {
				resolve(consumer, progress + 1);
			}
		}
		unset_cell(firstUnusedCell);
	}

	bool check_square() {
		for (int idx = 0; idx &lt; Size; ++idx) {
			if (!check_row(idx) || !check_col(idx)) {
				return false;
			}
		}

		if (!check_diag1() || !check_diag2()) {
			return false;
		}
		return true;
	}

	bool check_diag1() {
		int sum = 0;
		bool empty = false;
		for (int idx = 0; idx &lt; Size; ++idx) {
			int cell = get_cell(idx, idx);
			sum += cell;
			empty |= !cell;
			if (sum &gt; ROWSUM) {
				return false;
			}
		}

		return empty || sum == ROWSUM;
	}

	bool check_diag2() {
		int sum = 0;
		bool empty = false;
		for (int idx = 0; idx &lt; Size; ++idx) {
			int cell = get_cell(idx, Size - 1 - idx);
			sum += cell;
			empty |= !cell;
			if (sum &gt; ROWSUM) {
				return false;
			}
		}

		return empty || sum == ROWSUM;
	}

	bool check_col(int col) {
		int sum = 0;
		bool empty = false;
		for (int row = 0; row &lt; Size; ++row) {
			int cell = get_cell(row, col);
			sum += cell;
			empty |= !cell;
			if (sum &gt; ROWSUM) {
				return false;
			}
		}

		return empty || sum == ROWSUM;
	}

	bool check_row(int row) {
		int sum = 0;
		bool empty = false;
		for (int col = 0; col &lt; Size; ++col) {
			int cell = get_cell(row, col);
			sum += cell;
			empty |= !cell;
			if (sum &gt; ROWSUM) {
				return false;
			}
		}

		return empty || sum == ROWSUM;
	}

private:
	enum {
		FIELDS = Size * Size,
		ROWSUM = Size * (Size * Size + 1) / 2
	};

	inline int cell_id(int row, int col) {
		assert(row &lt; Size);
		assert(col &lt; Size);
		return row * Size + col;
	}

	inline void set_cell(int cell, int value) {
		assert(field[cell] == 0);
		assert(usedNumbers[value] == false);
		field[cell] = value;
		usedNumbers[value] = true;
	}

	inline void unset_cell(int cell) {
		usedNumbers[field[cell&rsqb;&rsqb; = false;
		field[cell] = 0;
	}

	inline int get_cell(int cell) {
		return field[cell];
	}

	inline void replace_cell(int cell, int value) {
		usedNumbers[field[cell&rsqb;&rsqb; = false;
		usedNumbers[value] = true;
		field[cell] = value;
	}

	std::array&lt;int, FIELDS&gt; field = { };
	std::array&lt;bool, FIELDS + 1&gt; usedNumbers = { };
};
</code></pre>
<pre><code>#include &lt;iostream&gt;
#include &lt;array&gt;
#include &lt;cstdio&gt;

#include &quot;MagicSquare.hpp&quot;

template&lt;int Size&gt;
void dumpSquare(MagicSquare&lt;Size&gt; &amp;square) {
	printf(&quot;----------------\n&quot;);
	for (int row = 0; row &lt; Size; row++) {
		for (int col = 0; col &lt; Size; col++) {
			printf(&quot;%2d &quot;, square.get_cell(row, col));
		}
		printf(&quot;\n&quot;);
	}
}

int main() {
	MagicSquare&lt;4&gt; square;
	square.resolve(&amp;dumpSquare);
	return 0;
}
</code></pre>
<p>Danke schonmal für eventuelles Feedback</p>
<p>Stummi</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/326783/erster-c-gehversuch-feedback-erwünscht</link><generator>RSS for Node</generator><lastBuildDate>Mon, 25 May 2026 04:48:26 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/326783.rss" rel="self" type="application/rss+xml"/><pubDate>Mon, 07 Jul 2014 12:17:37 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Erster C++-Gehversuch, Feedback erwünscht on Mon, 07 Jul 2014 12:17:37 GMT]]></title><description><![CDATA[<p>Hallo Forum,</p>
<p>ich komme ursprünglich aus der Java-Welt und mach grad mal meine ersten Gehversuche mit C++11.</p>
<p>Als &quot;Übungsprojekt&quot; habe ich mich jetzt einfach mal für einen Löser für Magische Quadrate beliebiger Größe entschieden:</p>
<p>- Es macht Sinn, das ganze auf Performance zu trimmen<br />
- Es beinhaltet ein paar grundlegende Templates<br />
- Später kann man darauf aufbauend sich schön mit Parallelisierung auseinandersetzen, denke ich.</p>
<p>Wie gesagt, das ganze ist ein erster Gehversuch und ich würde mich einfach gerne über ein bisschen Feedback freuen ob das ganze in die richtige Richtung geht. Zielplattform ist Linux und gcc. Interessiert bin ich nicht nur an &quot;echte&quot; Fehler sondern auch an Meinungen ob etwas &quot;Stilunüblich&quot; in der C++-Welt ist.</p>
<p>Gelöst wird das ganze folgendermaßen: Es wird rekursiv durch alle möglichen Kombinationen iteriert, also das nächste freie Feld einmal mit allen verbleibenden Zahlen gefüllt und dafür dann wieder die Funktion aufgerufen wird. Dabei wird aus einer &quot;Verzweigung&quot; ausgestiegen, sobald sich das Quadrat bei einer Prüfung als unlösbar herausstellt. Die methode bekommt einen Consumer als Funktionspointer, jedes gefundene fertige Quadrat wird an diesen Consumer zurückgegeben.</p>
<p>Also hier der Code:</p>
<pre><code>#pragma once

#include &lt;cassert&gt;
#include &lt;array&gt;

template&lt;int Size&gt;
class MagicSquare {
public:

	inline void unset_cell(int row, int col) {
		unset_cell(cell_id(row, col));
	}

	inline void set_cell(int row, int col, int val) {
		set_cell(cell_id(row, col), val);
	}

	inline int get_cell(int row, int col) {
		return get_cell(cell_id(row, col));
	}

	inline void replace_cell(int row, int col, int val) {
		replace_cell(cell_id(row, col), val);
	}

	int get_progress() {
		int prog = 0;
		for (int idx = 0; idx &lt; FIELDS; ++idx) {
			if (field[idx]) {
				++prog;
			}
		}
		return prog;
	}

	void resolve(void (*consumer)(MagicSquare&lt;Size&gt; &amp;)) {
		resolve(consumer, get_progress());
	}

	void resolve(void (*consumer)(MagicSquare&lt;Size&gt; &amp;), int progress) {
		if (progress == FIELDS) {
			consumer(*this);
		}

		int firstUnusedCell = 0;
		while (field[firstUnusedCell]) {
			++firstUnusedCell;
		}

		for (int idx = 1; idx &lt; FIELDS + 1; ++idx) {
			if (usedNumbers[idx]) {
				continue;
			}
			replace_cell(firstUnusedCell, idx);

			if (check_square()) {
				resolve(consumer, progress + 1);
			}
		}
		unset_cell(firstUnusedCell);
	}

	bool check_square() {
		for (int idx = 0; idx &lt; Size; ++idx) {
			if (!check_row(idx) || !check_col(idx)) {
				return false;
			}
		}

		if (!check_diag1() || !check_diag2()) {
			return false;
		}
		return true;
	}

	bool check_diag1() {
		int sum = 0;
		bool empty = false;
		for (int idx = 0; idx &lt; Size; ++idx) {
			int cell = get_cell(idx, idx);
			sum += cell;
			empty |= !cell;
			if (sum &gt; ROWSUM) {
				return false;
			}
		}

		return empty || sum == ROWSUM;
	}

	bool check_diag2() {
		int sum = 0;
		bool empty = false;
		for (int idx = 0; idx &lt; Size; ++idx) {
			int cell = get_cell(idx, Size - 1 - idx);
			sum += cell;
			empty |= !cell;
			if (sum &gt; ROWSUM) {
				return false;
			}
		}

		return empty || sum == ROWSUM;
	}

	bool check_col(int col) {
		int sum = 0;
		bool empty = false;
		for (int row = 0; row &lt; Size; ++row) {
			int cell = get_cell(row, col);
			sum += cell;
			empty |= !cell;
			if (sum &gt; ROWSUM) {
				return false;
			}
		}

		return empty || sum == ROWSUM;
	}

	bool check_row(int row) {
		int sum = 0;
		bool empty = false;
		for (int col = 0; col &lt; Size; ++col) {
			int cell = get_cell(row, col);
			sum += cell;
			empty |= !cell;
			if (sum &gt; ROWSUM) {
				return false;
			}
		}

		return empty || sum == ROWSUM;
	}

private:
	enum {
		FIELDS = Size * Size,
		ROWSUM = Size * (Size * Size + 1) / 2
	};

	inline int cell_id(int row, int col) {
		assert(row &lt; Size);
		assert(col &lt; Size);
		return row * Size + col;
	}

	inline void set_cell(int cell, int value) {
		assert(field[cell] == 0);
		assert(usedNumbers[value] == false);
		field[cell] = value;
		usedNumbers[value] = true;
	}

	inline void unset_cell(int cell) {
		usedNumbers[field[cell&rsqb;&rsqb; = false;
		field[cell] = 0;
	}

	inline int get_cell(int cell) {
		return field[cell];
	}

	inline void replace_cell(int cell, int value) {
		usedNumbers[field[cell&rsqb;&rsqb; = false;
		usedNumbers[value] = true;
		field[cell] = value;
	}

	std::array&lt;int, FIELDS&gt; field = { };
	std::array&lt;bool, FIELDS + 1&gt; usedNumbers = { };
};
</code></pre>
<pre><code>#include &lt;iostream&gt;
#include &lt;array&gt;
#include &lt;cstdio&gt;

#include &quot;MagicSquare.hpp&quot;

template&lt;int Size&gt;
void dumpSquare(MagicSquare&lt;Size&gt; &amp;square) {
	printf(&quot;----------------\n&quot;);
	for (int row = 0; row &lt; Size; row++) {
		for (int col = 0; col &lt; Size; col++) {
			printf(&quot;%2d &quot;, square.get_cell(row, col));
		}
		printf(&quot;\n&quot;);
	}
}

int main() {
	MagicSquare&lt;4&gt; square;
	square.resolve(&amp;dumpSquare);
	return 0;
}
</code></pre>
<p>Danke schonmal für eventuelles Feedback</p>
<p>Stummi</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2407383</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2407383</guid><dc:creator><![CDATA[Stummi]]></dc:creator><pubDate>Mon, 07 Jul 2014 12:17:37 GMT</pubDate></item><item><title><![CDATA[Reply to Erster C++-Gehversuch, Feedback erwünscht on Mon, 07 Jul 2014 12:38:58 GMT]]></title><description><![CDATA[<ul>
<li>Memberfunktionen die in der Klasse definiert werden sind implizit <code>inline</code> .</li>
<li>Größenangaben macht man mit<a href="http://en.cppreference.com/w/cpp/types/size_t" rel="nofollow"> <code>std::size_t</code> </a>, nicht <code>int</code> .</li>
<li>Statt einen Funktionszeiger zu nehmen, der dich nur limitiert, mach das ganze generisch:</li>
</ul>
<pre><code>template &lt;typename Callable&gt;
    void resolve( Callable consumer, int progress) {
        // [...]
</code></pre>
<p>Wird eine Funktion an dieses Funktionstemplate übergeben, wird für <code>Callable</code> ein Funktionszeigertyp deduziert. Der Rest bleibt völlig gleich - sowohl beim Callee als auch im Rumpf. Cool, was?</p>
<ul>
<li>Du verletzt <a href="http://en.wikipedia.org/wiki/Don%27t_repeat_yourself" rel="nofollow">DRY</a>. Die Funktionen <code>check_diag1</code> , <code>check_diag2</code> usw. sind sehr ähnlich.</li>
</ul>
<pre><code>template &lt;typename Callable&gt;
bool _internal_neat_function( Callable get_cell_call )
{
        int sum = 0;
        bool empty = false;
        for (int idx = 0; idx &lt; Size; ++idx) {
            int cell = get_cell_call(idx);
            sum += cell;
            empty |= !cell;
            if (sum &gt; ROWSUM)
                return false;
        }

        return empty || sum == ROWSUM;
}
</code></pre>
<p><img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/27a1.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--right_arrow"
      title=":arrow_right:"
      alt="➡"
    /></p>
<pre><code>bool check_diag1() {
        return _internal_neat_function( [] (int idx) {return get_cell(idx, idx);} );
    }
    bool check_diag2() {
        return _internal_neat_function( [] (int idx) {return get_cell(idx, Size - 1 - idx);} );
    }
    // ...
</code></pre>
<p>(alles ungetestet)<br />
Falls dir sowohl Funktionstemplate als auch Lambdas fremd sind - eigne sie dir an! Sind extrem coole und essentielle Features von C++.</p>
<ul>
<li>Z. 137-140: Warum eine Enumeration? Warum nicht einfach statische Member-Konstanten?</li>
</ul>
<pre><code>static const auto FIELDS = Size * Size;
</code></pre>
<p>Edit: Die genaue Funktionsweise deiner Algorithmen habe ich mir noch nicht angeschaut, auch die lässt sich wahrscheinlich optimieren.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2407387</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2407387</guid><dc:creator><![CDATA[Columbo]]></dc:creator><pubDate>Mon, 07 Jul 2014 12:38:58 GMT</pubDate></item><item><title><![CDATA[Reply to Erster C++-Gehversuch, Feedback erwünscht on Mon, 07 Jul 2014 12:35:49 GMT]]></title><description><![CDATA[<p>Nur ein paar Kleinigkeiten:</p>
<pre><code>empty |= !cell;
</code></pre>
<p>sieht komisch aus. Warum nicht einfach so?</p>
<pre><code>empty = !cell;
</code></pre>
<p>Anstelle der rohen Funktionszeiger könntest du mir mal <strong>std::function</strong> anschauen</p>
<p>Und über die Verwendung von <strong>printf</strong> in einem C++ Programm lässt sich natürlich streiten (anstelle von <strong>std::cout</strong>)</p>
<p>Und genaugenommen ist <strong>#pragma once</strong> kein Standardkonformes C++ (oder hat sich das inzwischen geändert?)</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2407388</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2407388</guid><dc:creator><![CDATA[asdfasd]]></dc:creator><pubDate>Mon, 07 Jul 2014 12:35:49 GMT</pubDate></item><item><title><![CDATA[Reply to Erster C++-Gehversuch, Feedback erwünscht on Mon, 07 Jul 2014 12:48:22 GMT]]></title><description><![CDATA[<p>asdfasd schrieb:</p>
<blockquote>
<pre><code>empty |= !cell;
</code></pre>
<p>sieht komisch aus. Warum nicht einfach so?</p>
<pre><code>empty = !cell;
</code></pre>
</blockquote>
<p>Weil das etwas anderes tut. Was wenn in <code>empty true</code> gespeichert ist und <code>!cell</code> den Wert <code>false</code> hat?</p>
<p>Besser wäre jedoch gleich den logischen Operator zu verwenden:</p>
<pre><code>empty ||= !cell;
</code></pre>
<blockquote>
<p>Anstelle der rohen Funktionszeiger könntest du mir mal std::function anschauen</p>
</blockquote>
<p>Ne, nicht gut. <code>function</code> ist hier unpassend.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2407391</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2407391</guid><dc:creator><![CDATA[Columbo]]></dc:creator><pubDate>Mon, 07 Jul 2014 12:48:22 GMT</pubDate></item><item><title><![CDATA[Reply to Erster C++-Gehversuch, Feedback erwünscht on Mon, 07 Jul 2014 12:45:50 GMT]]></title><description><![CDATA[<p>Arcoth schrieb:</p>
<blockquote>
<p>Besser wäre jedoch gleich den logischen Operator zu verwenden:</p>
<pre><code>empty ||= !cell;
</code></pre>
</blockquote>
<p>Diesen Operator gibt es nicht.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2407395</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2407395</guid><dc:creator><![CDATA[Fytch]]></dc:creator><pubDate>Mon, 07 Jul 2014 12:45:50 GMT</pubDate></item><item><title><![CDATA[Reply to Erster C++-Gehversuch, Feedback erwünscht on Mon, 07 Jul 2014 12:51:54 GMT]]></title><description><![CDATA[<pre><code>#pragma once

#include &lt;cassert&gt;
#include &lt;array&gt;

template&lt;int Size&gt;
class MagicSquare {
//Hier sollten die Attribute stehen, damit man 
public:

	inline void unset_cell(int row, int col) {
		unset_cell(cell_id(row, col));//hier weiß, um was es geht. 
		//So musste ich erst unten nachschauen. Ah, Du baust so ein Array2D. 
		//Naja, eine simple int&amp; at(int x,int y) hötte das auch abgedeckt. 
	}

	inline void set_cell(int row, int col, int val) {//übrigens brauchste inline nie hinzuschreiben, 
	//das macht der compiler eh wie er will. 
		set_cell(cell_id(row, col), val);
	}

	inline int get_cell(int row, int col) {
		return get_cell(cell_id(row, col));
	}

	inline void replace_cell(int row, int col, int val) {
		replace_cell(cell_id(row, col), val);
	}
	//Die letzten VIER Funktionen waren daher ein wenig übertrieben. 

	int get_progress() {
		int prog = 0;
		for (int idx = 0; idx &lt; FIELDS; ++idx) {//Das ist lahm. Lieber prog als Attribut mitführen. 
			if (field[idx]) {
				++prog;
			}
		}
		return prog;
	}

	void resolve(void (*consumer)(MagicSquare&lt;Size&gt; &amp;)) {//funktionszeiger statt funktionsobjekt ist lahmer. 
		resolve(consumer, get_progress());//und was das hier soll, weiß ich gar nicht. 
	}

	void resolve(void (*consumer)(MagicSquare&lt;Size&gt; &amp;), int progress) {//Das nervt, daß Du gleichname Wrapper 
	//schreibst, satt Dir als erste Zeile eine Variable zu besorgen. Immer noch nicht klar, was &quot;resolve&quot; heißt. 
		if (progress == FIELDS) {
			consumer(*this);
		}

		int firstUnusedCell = 0;
		while (field[firstUnusedCell]) {
			++firstUnusedCell;//Bis fast sicher, das würde vom Attribut prog vollkommen übernommen werden können. 
			//Momentchen, warum nicht sowas ähnliches wie fisher-yates-shuffle? 
			//Oder std::next_permutation. 
		}

		for (int idx = 1; idx &lt; FIELDS + 1; ++idx) {
			if (usedNumbers[idx]) {
				continue;
			}
			replace_cell(firstUnusedCell, idx);

			if (check_square()) {
				resolve(consumer, progress + 1);//Ah, der rekursive Aufruf. Ohne den Wrapper?
			}
		}
		unset_cell(firstUnusedCell);
	}

	bool check_square() {
		for (int idx = 0; idx &lt; Size; ++idx) {
			if (!check_row(idx) || !check_col(idx)) {
				return false;
			}
		}

		if (!check_diag1() || !check_diag2()) {
			return false;
		}
		return true;
		//Die war hübsch einfach. 
	}

	bool check_diag1() {
		int sum = 0;
		bool empty = false;
		for (int idx = 0; idx &lt; Size; ++idx) {
			int cell = get_cell(idx, idx);
			sum += cell;
			empty |= !cell;//Die Zeile wird Arcoth gefallen. 
			if (sum &gt; ROWSUM) {
				return false;
			}
		}

		return empty || sum == ROWSUM;
	}

	bool check_diag2() {
		int sum = 0;//Ganzschön gleich die letzten 2 Funktionen. Kann man zusammenlegen. 
		bool empty = false;
		for (int idx = 0; idx &lt; Size; ++idx) {
			int cell = get_cell(idx, Size - 1 - idx);
			sum += cell;
			empty |= !cell;
			if (sum &gt; ROWSUM) {
				return false;
			}
		}

		return empty || sum == ROWSUM;
	}

	bool check_col(int col) {
		int sum = 0;//Ganzschön gleich die letzten 3 Funktionen. Kann man zusammenlegen. 
		bool empty = false;
		for (int row = 0; row &lt; Size; ++row) {
			int cell = get_cell(row, col);
			sum += cell;
			empty |= !cell;
			if (sum &gt; ROWSUM) {
				return false;
			}
		}

		return empty || sum == ROWSUM;
	}

	bool check_row(int row) {
		int sum = 0;//Ganzschön gleich die letzten 4 Funktionen. Kann man zusammenlegen. 
		bool empty = false;
		for (int col = 0; col &lt; Size; ++col) {
			int cell = get_cell(row, col);
			sum += cell;
			empty |= !cell;
			if (sum &gt; ROWSUM) {
				return false;
			}
		}

		return empty || sum == ROWSUM;
	}

private:
	enum {//Nee, static const
		FIELDS = Size * Size,
		ROWSUM = Size * (Size * Size + 1) / 2//Gut, die vorzuberechnen
	};

	inline int cell_id(int row, int col) {
		assert(row &lt; Size);
		assert(col &lt; Size);
		return row * Size + col;
	}

	inline void set_cell(int cell, int value) {
		assert(field[cell] == 0);//ahm dafür in set, unset, replace aufgeteilt. 
		assert(usedNumbers[value] == false);
		field[cell] = value;
		usedNumbers[value] = true;
	}

	inline void unset_cell(int cell) {
		usedNumbers[field[cell&rsqb;&rsqb; = false;
		field[cell] = 0;
	}

	inline int get_cell(int cell) {
		return field[cell];
	}

	inline void replace_cell(int cell, int value) {
		usedNumbers[field[cell&rsqb;&rsqb; = false;
		usedNumbers[value] = true;
		field[cell] = value;
	}

	std::array&lt;int, FIELDS&gt; field = { };
	std::array&lt;bool, FIELDS + 1&gt; usedNumbers = { };
};
</code></pre>
<pre><code>#include &lt;iostream&gt;
#include &lt;array&gt;
#include &lt;cstdio&gt;

#include &quot;MagicSquare.hpp&quot;

template&lt;int Size&gt;
void dumpSquare(MagicSquare&lt;Size&gt; &amp;square) {
	printf(&quot;----------------\n&quot;);
	for (int row = 0; row &lt; Size; row++) {//viele bevorzugen != und präinkrement
		for (int col = 0; col &lt; Size; col++) {
			printf(&quot;%2d &quot;, square.get_cell(row, col));//printf
		}
		printf(&quot;\n&quot;);
	}
}

int main() {
	MagicSquare&lt;4&gt; square;
	square.resolve(&amp;dumpSquare);
	return 0;
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2407396</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2407396</guid><dc:creator><![CDATA[volkard]]></dc:creator><pubDate>Mon, 07 Jul 2014 12:51:54 GMT</pubDate></item><item><title><![CDATA[Reply to Erster C++-Gehversuch, Feedback erwünscht on Mon, 07 Jul 2014 12:53:55 GMT]]></title><description><![CDATA[<p>Arcoth schrieb:</p>
<blockquote>
<p>[*]Du verletzt <a href="http://en.wikipedia.org/wiki/Don%27t_repeat_yourself" rel="nofollow">DRY</a>.</p>
</blockquote>
<p>Das war mir klar, aber nicht wie ich es besser machen könnte. Danke für den Verweis auf Lambdas und Funktionszeiter, da werde ich mich nochmal genauer einlesen. Dein Codebeispiel bringt mir aber einen Fehler:</p>
<blockquote>
<p>../MagicSquare.hpp:93:43: error: ‘this’ was not captured for this lambda function</p>
</blockquote>
<p>Grüße,<br />
Stummi</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2407398</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2407398</guid><dc:creator><![CDATA[Stummi]]></dc:creator><pubDate>Mon, 07 Jul 2014 12:53:55 GMT</pubDate></item><item><title><![CDATA[Reply to Erster C++-Gehversuch, Feedback erwünscht on Mon, 07 Jul 2014 12:59:57 GMT]]></title><description><![CDATA[<p>asdfasd schrieb:</p>
<blockquote>
<p>Und genaugenommen ist <strong>#pragma once</strong> kein Standardkonformes C++ (oder hat sich das inzwischen geändert?)</p>
</blockquote>
<p>Pragma-Direktiven sind definitionsgemäß implementationsspezifisch und damit kein Teil des C++ Standards auch wenn diese mittlerweile meines Wisens nach von allen gängigen Compilern unterstützt wird.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2407400</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2407400</guid><dc:creator><![CDATA[TNA]]></dc:creator><pubDate>Mon, 07 Jul 2014 12:59:57 GMT</pubDate></item><item><title><![CDATA[Reply to Erster C++-Gehversuch, Feedback erwünscht on Mon, 07 Jul 2014 13:00:57 GMT]]></title><description><![CDATA[<p>Stummi schrieb:</p>
<blockquote>
<blockquote>
<p>../MagicSquare.hpp:93:43: error: ‘this’ was not captured for this lambda function</p>
</blockquote>
</blockquote>
<p>Ja, du musst noch this capturen, sonst kann das Lambda keine Memberfunktionen aufrufen.<br />
Einfach this in die eckigen Klammern schreiben.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2407401</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2407401</guid><dc:creator><![CDATA[Nathan]]></dc:creator><pubDate>Mon, 07 Jul 2014 13:00:57 GMT</pubDate></item><item><title><![CDATA[Reply to Erster C++-Gehversuch, Feedback erwünscht on Mon, 07 Jul 2014 13:01:14 GMT]]></title><description><![CDATA[<p>asfdlol schrieb:</p>
<blockquote>
<p>Diesen Operator gibt es nicht.</p>
</blockquote>
<p><strong>Tatsächlich</strong>! Ich werd' verrückt! Bist du gerade in der Zeit zurückgereist und hast diesen Operator aus jeglichen Standardisierungen von C und C++ entfernt?</p>
<p>Gut, schreiben wir es aus, immer noch besser:</p>
<pre><code>empty = empty || !cell;
</code></pre>
<blockquote>
<p>Die Zeile wird Arcoth gefallen.</p>
</blockquote>
<p>Ist es vom <em>Standard</em> definiert dass <code>true | false</code> wiederum <code>true</code> oder <code>false</code> ergibt? Siehe auch <a href="http://www.c-plusplus.net/forum/p2405212#2405212" rel="nofollow">hier</a>.</p>
<blockquote>
<p>Dein Codebeispiel bringt mir aber einen Fehler:</p>
</blockquote>
<p>Upsi. Schreib das Lambda in beiden Fällen zu</p>
<pre><code>[this] (int idx) {return get_cell(idx, idx);}
</code></pre>
<p>um, und probier' noch mal.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2407402</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2407402</guid><dc:creator><![CDATA[Columbo]]></dc:creator><pubDate>Mon, 07 Jul 2014 13:01:14 GMT</pubDate></item><item><title><![CDATA[Reply to Erster C++-Gehversuch, Feedback erwünscht on Mon, 07 Jul 2014 13:13:07 GMT]]></title><description><![CDATA[<blockquote>
<p>funktionszeiger statt funktionsobjekt ist lahmer.</p>
</blockquote>
<p>Ein Funktionszeiger <strong>ist</strong> ein Funktionsobjekt. Ein Funktionsobjekt ist dadurch definiert dass man es wie eine Funktion aufrufen kann. Und was heißt &quot;Lahm&quot;*? Ich hoffe &quot;uncooler&quot;.</p>
<p>Übrigens:</p>
<pre><code>if (!check_diag1() || !check_diag2()) {
            return false;
        }
        return true;
</code></pre>
<p><img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/27a1.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--right_arrow"
      title=":arrow_right:"
      alt="➡"
    /></p>
<pre><code>return check_diag1() &amp;&amp; check_diag2();
</code></pre>
<p><a href="http://de.wikipedia.org/wiki/De_Morgansche_Gesetze" rel="nofollow">De Morgansche Gesetze</a> und so.</p>
<p>* Außenverteidiger!</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2407403</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2407403</guid><dc:creator><![CDATA[Columbo]]></dc:creator><pubDate>Mon, 07 Jul 2014 13:13:07 GMT</pubDate></item><item><title><![CDATA[Reply to Erster C++-Gehversuch, Feedback erwünscht on Mon, 07 Jul 2014 13:15:21 GMT]]></title><description><![CDATA[<p>Arcoth schrieb:</p>
<blockquote>
<p><strong>Tatsächlich</strong>! Ich werd' verrückt! Bist du gerade in der Zeit zurückgereist und hast diesen Operator aus jeglichen Standardisierungen von C und C++ entfernt?</p>
</blockquote>
<p>Das hab ich damals schon vor Ort vollbracht. <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 />
Spass beiseite. Die Tatsache, dass diese Operatoren und dass der ^^-Operator (Logisch-XOR) fehlen haben mich schon aufgeregt.</p>
<p>Arcoth schrieb:</p>
<blockquote>
<p>Ist es vom <em>Standard</em> definiert dass <code>true | false</code> wiederum <code>true</code> oder <code>false</code> ergibt? Siehe auch <a href="http://www.c-plusplus.net/forum/p2405212#2405212" rel="nofollow">hier</a>.</p>
</blockquote>
<p>Darüber habe ich mir auch schon Gedanken gemacht. Einmal hat jemand hier im Forum einen Ausschnitt aus dem Standard gepostet (das war SeppJ glaub ich, ich finde den Beitrag jedoch nicht mehr, das ist ein Weilchen her, vermutlich noch auf einem meiner alten Accouts), dass dies (und dasselbe mit XOR) wohldefiniert ist. Nachdem camper in dem von dir verlinkten Thread etwas anderes (und genaueres) geschrieben hat bin ich unsicher.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2407405</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2407405</guid><dc:creator><![CDATA[Fytch]]></dc:creator><pubDate>Mon, 07 Jul 2014 13:15:21 GMT</pubDate></item><item><title><![CDATA[Reply to Erster C++-Gehversuch, Feedback erwünscht on Mon, 07 Jul 2014 13:17:27 GMT]]></title><description><![CDATA[<p>Arcoth schrieb:</p>
<blockquote>
<blockquote>
<p>funktionszeiger statt funktionsobjekt ist lahmer.</p>
</blockquote>
<p>Ein Funktionszeiger <strong>ist</strong> ein Funktionsobjekt. Ein Funktionsobjekt ist dadurch definiert dass man es wie eine Funktion aufrufen kann. Und was heißt &quot;Lahm&quot;*? Ich hoffe &quot;uncooler&quot;.</p>
<p>Übrigens:</p>
<pre><code>if (!check_diag1() || !check_diag2()) {
            return false;
        }
        return true;
</code></pre>
<p><img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/27a1.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--right_arrow"
      title=":arrow_right:"
      alt="➡"
    /></p>
<pre><code>return check_diag1() &amp;&amp; check_diag2();
</code></pre>
<p><a href="http://de.wikipedia.org/wiki/De_Morgansche_Gesetze" rel="nofollow">De Morgansche Gesetze</a> und so.</p>
<p>* Außenverteidiger!</p>
</blockquote>
<p>Nöö, das war schon sehr gut so.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2407406</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2407406</guid><dc:creator><![CDATA[volkard]]></dc:creator><pubDate>Mon, 07 Jul 2014 13:17:27 GMT</pubDate></item><item><title><![CDATA[Reply to Erster C++-Gehversuch, Feedback erwünscht on Mon, 07 Jul 2014 13:18:39 GMT]]></title><description><![CDATA[<p>asfdlol schrieb:</p>
<blockquote>
<p>Arcoth schrieb:</p>
<blockquote>
<p><strong>Tatsächlich</strong>! Ich werd' verrückt! Bist du gerade in der Zeit zurückgereist und hast diesen Operator aus jeglichen Standardisierungen von C und C++ entfernt?</p>
</blockquote>
<p>Das hab ich damals schon vor Ort vollbracht. <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 />
Spass beiseite. Die Tatsache, dass diese Operatoren und dass der ^^-Operator (Logisch-XOR) fehlen haben mich schon aufgeregt.</p>
</blockquote>
<p>Den ^^ gibts, nur heißt er !=.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2407408</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2407408</guid><dc:creator><![CDATA[volkard]]></dc:creator><pubDate>Mon, 07 Jul 2014 13:18:39 GMT</pubDate></item><item><title><![CDATA[Reply to Erster C++-Gehversuch, Feedback erwünscht on Mon, 07 Jul 2014 13:29:19 GMT]]></title><description><![CDATA[<p>volkard schrieb:</p>
<blockquote>
<p>Den ^^ gibts, nur heißt er !=.</p>
</blockquote>
<p>Ich hab zwar keine Ahnung wie <code>bool</code> s miteinander verglichen werden, aber wenn die oberen Bits über dem achten unspezifiziert sind, dann kann so ein <code>!=</code> doch schief gehen, oder? Oder wird beim Vergleich nur das LSB betrachtet?</p>
<p>Edit: Ich sage besser nichts dazu, ich weiss nicht was der Standard über <code>bool</code> s aussagt. Nicht auf mich hören also!</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2407409</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2407409</guid><dc:creator><![CDATA[Fytch]]></dc:creator><pubDate>Mon, 07 Jul 2014 13:29:19 GMT</pubDate></item><item><title><![CDATA[Reply to Erster C++-Gehversuch, Feedback erwünscht on Mon, 07 Jul 2014 13:31:23 GMT]]></title><description><![CDATA[<p>asfdlol schrieb:</p>
<blockquote>
<p>volkard schrieb:</p>
<blockquote>
<p>Den ^^ gibts, nur heißt er !=.</p>
</blockquote>
<p>Ich hab zwar keine Ahnung wie <code>bool</code> s miteinander verglichen werden, aber wenn die oberen Bits über dem achten unspezifiziert sind, dann kann so ein <code>!=</code> doch schief gehen, oder? Oder wird beim Vergleich nur das LSB betrachtet?</p>
<p>Edit: Ich sage besser nichts dazu, ich weiss nicht was der Standard über <code>bool</code> s aussagt. Nicht auf mich hören also!</p>
</blockquote>
<p>Ich geh einfach mal davon aus, dass Vergleiche für bools schon definiert sind und zwei gleiche immer gleich sind und nicht auf einmal verschieden, wenn da anderer Müll ist. Das wäre sonst ziemlich blöd.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2407410</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2407410</guid><dc:creator><![CDATA[Nathan]]></dc:creator><pubDate>Mon, 07 Jul 2014 13:31:23 GMT</pubDate></item><item><title><![CDATA[Reply to Erster C++-Gehversuch, Feedback erwünscht on Mon, 07 Jul 2014 14:11:24 GMT]]></title><description><![CDATA[<p>asfdlol schrieb:</p>
<blockquote>
<p>Arcoth schrieb:</p>
<blockquote>
<p>Ist es vom <em>Standard</em> definiert dass <code>true | false</code> wiederum <code>true</code> oder <code>false</code> ergibt? Siehe auch <a href="http://www.c-plusplus.net/forum/p2405212#2405212" rel="nofollow">hier</a>.</p>
</blockquote>
<p>Darüber habe ich mir auch schon Gedanken gemacht. Einmal hat jemand hier im Forum einen Ausschnitt aus dem Standard gepostet (das war SeppJ glaub ich, ich finde den Beitrag jedoch nicht mehr, das ist ein Weilchen her, vermutlich noch auf einem meiner alten Accouts), dass dies (und dasselbe mit XOR) wohldefiniert ist. Nachdem camper in dem von dir verlinkten Thread etwas anderes (und genaueres) geschrieben hat bin ich unsicher.</p>
</blockquote>
<p>true | false ergibt 1<br />
Was ich in dem Thread geschrieben habe bezog sich auf die ABI - mithin das was nach der Übersetzung in Assembler-/Maschinencode zu beachten ist. Mit dem Verhalten auf der Ebene von C++ hat das nichts zu tun: | führt erst mal die gewöhnlich arithmetischen Konvertierungen auf beiden Operanden aus (weil es nur für int und größere integrale Typen definiert ist). Und die Konvertierung von bool nach int ergibt immer 1 bzw. 0 für true bzw. false.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2407415</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2407415</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Mon, 07 Jul 2014 14:11:24 GMT</pubDate></item></channel></rss>