<?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[Templates und deren Grenzen]]></title><description><![CDATA[<p>Hi - ich mal wieder ^^<br />
Ich habe mich vorhin mal hingesetzt um meine Matrix-Klasse zu überarbeiten und hab std::vector durch nen Zeiger ersetzt - dessen Dimension soll aber ein template-Argument bleiben - also habe ich folgenden Schnipsel geschrieben:</p>
<pre><code class="language-cpp">template &lt;typename Tsizetype, Tsizetype line_count, Tsizetype row_count, typename Tvaluetype&gt;
class TMatrix
{
public:
	typedef Tvaluetype				ValueType;
	typedef Tsizetype				SizeType;

	static const SizeType			m		= row_count;
	static const SizeType			n		= line_count;

	class Line
	{
	private:
		ValueType *values;
		Line&amp; operator = (const Line&amp; rhs);
		Line (const Line&amp; rhs);
	public:
		Line()
			:	values(new ValueType[row_count])
		{}

		void swap(Line &amp;lhs, Line &amp;rhs)
		{
			std::swap (lhs.values, rhs.values);
		}

		~Line()
		{
			delete []values;
		}

		ValueType&amp; operator[] (Tsizetype i)
		{
			assert (i &lt; row_count);
			return (values[i]);
		}

		const ValueType&amp; operator[] (Tsizetype i) const
		{
			assert (i &lt; row_count);
			return (values[i]);
		}

	};

private:
	Line *lines;
	TMatrix (const TMatrix &amp;);
	TMatrix&amp; operator = (const TMatrix &amp;);
public:
	Line&amp; operator[] (Tsizetype i)
	{
		assert (i &lt; line_count);
		return (lines[i]);
	}

	const Line&amp; operator[] (Tsizetype i) const
	{
		assert (i &lt; line_count);
		return (lines[i]);
	}

	TMatrix()
		:	lines(new Line[line_count])
	{}

	~TMatrix()
	{
		delete []lines;
	}
};
</code></pre>
<p>und eine Funktion die mein Compiler leider nicht ganz überblicken kann (er ignoriert die untere Grenze wie auch an der Fehlermeldung ganz unten erkennbar wird:</p>
<pre><code class="language-cpp">template &lt;typename Treturnvaluetype, typename Tsizetype, Tsizetype dim, typename Tvaluetype&gt;
Treturnvaluetype Determinant_LaPlace (const TMatrix &lt;Tsizetype, dim, dim, Tvaluetype&gt; &amp;thismatrix)
{
	if (dim &gt;= 3)
	{
		Treturnvaluetype sum = Treturnvaluetype();
		const Tsizetype nextdim (dim-1);

		typedef TMatrix &lt;Tsizetype, dim, dim, Tvaluetype&gt; TThisMatrix;
		typedef TMatrix &lt;Tsizetype, nextdim, nextdim, Tvaluetype&gt; TNextMatrix;

		TNextMatrix nextmatrix;

		for (Tsizetype m = Tsizetype(); m != nextdim; ++m)
		{
			for (Tsizetype n = Tsizetype(); n != nextdim; ++n)
			{
				TNextMatrix::Line &amp;line_to = nextmatrix[n];
				const TThisMatrix::Line &amp;line_from = thismatrix[n+1];

				for (Tsizetype i = Tsizetype(); i != n; ++i)
				{
					line_to[i] = line_from[i];
				}
				for (Tsizetype i (n); i != nextdim; ++i)
				{
					line_to[i] = line_from[i+1];
				}
			}
			sum += thismatrix[0][m] * Determinant_LaPlace &lt;Treturnvaluetype&gt; (nextmatrix);
		}
		return sum;
	}
	else if (dim == 2)
	{
		return Treturnvaluetype(thismatrix[0][0] * thismatrix[1][1] - thismatrix[0][1] * thismatrix[1][0]);
	}
	else
	{
		throw std::invalid_argument (&quot;Dimension needs to be bigger then one&quot;);
	}
}
</code></pre>
<p>Die Fehlermeldung:</p>
<pre><code>1&gt;------ Build started: Project: test, Configuration: Debug Win32 ------
1&gt;Compiling...
1&gt;main.cpp
1&gt;f:\c\libs\math\matrix.hpp(85) : error C2148: total size of array must not exceed 0x7fffffff bytes
1&gt;        f:\c\libs\math\matrix.hpp(85) : while compiling class template member function 'my::TMatrix&lt;Tsizetype,line_count,row_count,Tvaluetype&gt;::TMatrix(void)'
1&gt;        with
1&gt;        [
1&gt;            Tsizetype=size_t,
1&gt;            line_count=-1,
1&gt;            row_count=-1,
1&gt;            Tvaluetype=char
1&gt;        ]
1&gt;        f:\c\libs\math\matrix.hpp(330) : see reference to class template instantiation 'my::TMatrix&lt;Tsizetype,line_count,row_count,Tvaluetype&gt;' being compiled
1&gt;        with
1&gt;        [
1&gt;            Tsizetype=size_t,
1&gt;            line_count=-1,
1&gt;            row_count=-1,
1&gt;            Tvaluetype=char
1&gt;        ]
1&gt;        f:\c\libs\math\matrix.hpp(348) : see reference to function template instantiation 'Treturnvaluetype my::math::Determinant_LaPlace&lt;Treturnvaluetype,Tsizetype,0,Tvaluetype&gt;(const my::TMatrix&lt;Tsizetype,line_count,row_count,Tvaluetype&gt; &amp;)' being compiled
1&gt;        with
1&gt;        [
1&gt;            Treturnvaluetype=float,
1&gt;            Tsizetype=size_t,
1&gt;            Tvaluetype=char,
1&gt;            line_count=0,
1&gt;            row_count=0
1&gt;        ]
1&gt;        f:\c\libs\math\matrix.hpp(348) : see reference to function template instantiation 'Treturnvaluetype my::math::Determinant_LaPlace&lt;Treturnvaluetype,Tsizetype,1,Tvaluetype&gt;(const my::TMatrix&lt;Tsizetype,line_count,row_count,Tvaluetype&gt; &amp;)' being compiled
1&gt;        with
1&gt;        [
1&gt;            Treturnvaluetype=float,
1&gt;            Tsizetype=size_t,
1&gt;            Tvaluetype=char,
1&gt;            line_count=1,
1&gt;            row_count=1
1&gt;        ]
1&gt;        c:\users\tommy\documents\visual studio 2008\projects\test\test\main.cpp(13) : see reference to function template instantiation 'Treturnvaluetype my::math::Determinant_LaPlace&lt;float,size_t,2,char&gt;(const my::TMatrix&lt;Tsizetype,line_count,row_count,Tvaluetype&gt; &amp;)' being compiled
1&gt;        with
1&gt;        [
1&gt;            Treturnvaluetype=float,
1&gt;            Tsizetype=size_t,
1&gt;            line_count=2,
1&gt;            row_count=2,
1&gt;            Tvaluetype=char
1&gt;        ]
1&gt;f:\c\libs\math\matrix.hpp(85) : warning C4307: '*' : integral constant overflow
1&gt;f:\c\libs\math\matrix.hpp(85) : warning C4307: '+' : integral constant overflow
1&gt;f:\c\libs\math\matrix.hpp(85) : error C2148: total size of array must not exceed 0x7fffffff bytes
1&gt;Build log was saved at &quot;file://c:\Users\Tommy\Documents\Visual Studio 2008\Projects\test\test\Debug\BuildLog.htm&quot;
1&gt;test - 2 error(s), 2 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
</code></pre>
<p>Der Code der diesen Fehler erzeugt hat sieht so aus:</p>
<pre><code class="language-cpp">my::TMatrix &lt;size_t, 2, 2, char&gt; eins;
eins[0][0] = 2;
eins[0][1] = 0;
eins[1][1] = 1;

float det = my::math::Determinant_LaPlace &lt;float&gt; (eins);
</code></pre>
<p>Wie bekomm ich es hin, dass mein Compiler merkt, dass er das template nicht für eine negative anzahl an zeilen/spalten erzeugen soll?<br />
Oder geht das nicht mal eben mit ner anderen Schreibweise?</p>
<p>Würder ihr die Dimensionen überhaupt über Templates lösen oder etwa erst zur Laufzeit ermitteln (was ja Probleme bei sämtlichen Operatoren mit sich bringen würde: Bsp.: Addition 2er Matrizen, Determinante, Vergleiche, ...)</p>
<p>Danke schon mal : &gt;</p>
<p>PS: Bitte keine Vorschläge statt des Pointers einen STL-Container oder ein Array auf dem Stack zu nehmen (was ja das Problem auch nicht behebt) - da die Stack-Größe eines Prozesses sehr stark (zumindest im Vergleich zum Heap) begrentzt ist, möchte ich mir dadurch keine Obergrenze setzen - so weit ich weiß speichert auch std::tr1::array seinen Inhalt auf dem Stack, oder?</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/229662/templates-und-deren-grenzen</link><generator>RSS for Node</generator><lastBuildDate>Sun, 27 Sep 2026 11:08:56 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/229662.rss" rel="self" type="application/rss+xml"/><pubDate>Mon, 15 Dec 2008 01:03:35 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Templates und deren Grenzen on Mon, 15 Dec 2008 01:03:35 GMT]]></title><description><![CDATA[<p>Hi - ich mal wieder ^^<br />
Ich habe mich vorhin mal hingesetzt um meine Matrix-Klasse zu überarbeiten und hab std::vector durch nen Zeiger ersetzt - dessen Dimension soll aber ein template-Argument bleiben - also habe ich folgenden Schnipsel geschrieben:</p>
<pre><code class="language-cpp">template &lt;typename Tsizetype, Tsizetype line_count, Tsizetype row_count, typename Tvaluetype&gt;
class TMatrix
{
public:
	typedef Tvaluetype				ValueType;
	typedef Tsizetype				SizeType;

	static const SizeType			m		= row_count;
	static const SizeType			n		= line_count;

	class Line
	{
	private:
		ValueType *values;
		Line&amp; operator = (const Line&amp; rhs);
		Line (const Line&amp; rhs);
	public:
		Line()
			:	values(new ValueType[row_count])
		{}

		void swap(Line &amp;lhs, Line &amp;rhs)
		{
			std::swap (lhs.values, rhs.values);
		}

		~Line()
		{
			delete []values;
		}

		ValueType&amp; operator[] (Tsizetype i)
		{
			assert (i &lt; row_count);
			return (values[i]);
		}

		const ValueType&amp; operator[] (Tsizetype i) const
		{
			assert (i &lt; row_count);
			return (values[i]);
		}

	};

private:
	Line *lines;
	TMatrix (const TMatrix &amp;);
	TMatrix&amp; operator = (const TMatrix &amp;);
public:
	Line&amp; operator[] (Tsizetype i)
	{
		assert (i &lt; line_count);
		return (lines[i]);
	}

	const Line&amp; operator[] (Tsizetype i) const
	{
		assert (i &lt; line_count);
		return (lines[i]);
	}

	TMatrix()
		:	lines(new Line[line_count])
	{}

	~TMatrix()
	{
		delete []lines;
	}
};
</code></pre>
<p>und eine Funktion die mein Compiler leider nicht ganz überblicken kann (er ignoriert die untere Grenze wie auch an der Fehlermeldung ganz unten erkennbar wird:</p>
<pre><code class="language-cpp">template &lt;typename Treturnvaluetype, typename Tsizetype, Tsizetype dim, typename Tvaluetype&gt;
Treturnvaluetype Determinant_LaPlace (const TMatrix &lt;Tsizetype, dim, dim, Tvaluetype&gt; &amp;thismatrix)
{
	if (dim &gt;= 3)
	{
		Treturnvaluetype sum = Treturnvaluetype();
		const Tsizetype nextdim (dim-1);

		typedef TMatrix &lt;Tsizetype, dim, dim, Tvaluetype&gt; TThisMatrix;
		typedef TMatrix &lt;Tsizetype, nextdim, nextdim, Tvaluetype&gt; TNextMatrix;

		TNextMatrix nextmatrix;

		for (Tsizetype m = Tsizetype(); m != nextdim; ++m)
		{
			for (Tsizetype n = Tsizetype(); n != nextdim; ++n)
			{
				TNextMatrix::Line &amp;line_to = nextmatrix[n];
				const TThisMatrix::Line &amp;line_from = thismatrix[n+1];

				for (Tsizetype i = Tsizetype(); i != n; ++i)
				{
					line_to[i] = line_from[i];
				}
				for (Tsizetype i (n); i != nextdim; ++i)
				{
					line_to[i] = line_from[i+1];
				}
			}
			sum += thismatrix[0][m] * Determinant_LaPlace &lt;Treturnvaluetype&gt; (nextmatrix);
		}
		return sum;
	}
	else if (dim == 2)
	{
		return Treturnvaluetype(thismatrix[0][0] * thismatrix[1][1] - thismatrix[0][1] * thismatrix[1][0]);
	}
	else
	{
		throw std::invalid_argument (&quot;Dimension needs to be bigger then one&quot;);
	}
}
</code></pre>
<p>Die Fehlermeldung:</p>
<pre><code>1&gt;------ Build started: Project: test, Configuration: Debug Win32 ------
1&gt;Compiling...
1&gt;main.cpp
1&gt;f:\c\libs\math\matrix.hpp(85) : error C2148: total size of array must not exceed 0x7fffffff bytes
1&gt;        f:\c\libs\math\matrix.hpp(85) : while compiling class template member function 'my::TMatrix&lt;Tsizetype,line_count,row_count,Tvaluetype&gt;::TMatrix(void)'
1&gt;        with
1&gt;        [
1&gt;            Tsizetype=size_t,
1&gt;            line_count=-1,
1&gt;            row_count=-1,
1&gt;            Tvaluetype=char
1&gt;        ]
1&gt;        f:\c\libs\math\matrix.hpp(330) : see reference to class template instantiation 'my::TMatrix&lt;Tsizetype,line_count,row_count,Tvaluetype&gt;' being compiled
1&gt;        with
1&gt;        [
1&gt;            Tsizetype=size_t,
1&gt;            line_count=-1,
1&gt;            row_count=-1,
1&gt;            Tvaluetype=char
1&gt;        ]
1&gt;        f:\c\libs\math\matrix.hpp(348) : see reference to function template instantiation 'Treturnvaluetype my::math::Determinant_LaPlace&lt;Treturnvaluetype,Tsizetype,0,Tvaluetype&gt;(const my::TMatrix&lt;Tsizetype,line_count,row_count,Tvaluetype&gt; &amp;)' being compiled
1&gt;        with
1&gt;        [
1&gt;            Treturnvaluetype=float,
1&gt;            Tsizetype=size_t,
1&gt;            Tvaluetype=char,
1&gt;            line_count=0,
1&gt;            row_count=0
1&gt;        ]
1&gt;        f:\c\libs\math\matrix.hpp(348) : see reference to function template instantiation 'Treturnvaluetype my::math::Determinant_LaPlace&lt;Treturnvaluetype,Tsizetype,1,Tvaluetype&gt;(const my::TMatrix&lt;Tsizetype,line_count,row_count,Tvaluetype&gt; &amp;)' being compiled
1&gt;        with
1&gt;        [
1&gt;            Treturnvaluetype=float,
1&gt;            Tsizetype=size_t,
1&gt;            Tvaluetype=char,
1&gt;            line_count=1,
1&gt;            row_count=1
1&gt;        ]
1&gt;        c:\users\tommy\documents\visual studio 2008\projects\test\test\main.cpp(13) : see reference to function template instantiation 'Treturnvaluetype my::math::Determinant_LaPlace&lt;float,size_t,2,char&gt;(const my::TMatrix&lt;Tsizetype,line_count,row_count,Tvaluetype&gt; &amp;)' being compiled
1&gt;        with
1&gt;        [
1&gt;            Treturnvaluetype=float,
1&gt;            Tsizetype=size_t,
1&gt;            line_count=2,
1&gt;            row_count=2,
1&gt;            Tvaluetype=char
1&gt;        ]
1&gt;f:\c\libs\math\matrix.hpp(85) : warning C4307: '*' : integral constant overflow
1&gt;f:\c\libs\math\matrix.hpp(85) : warning C4307: '+' : integral constant overflow
1&gt;f:\c\libs\math\matrix.hpp(85) : error C2148: total size of array must not exceed 0x7fffffff bytes
1&gt;Build log was saved at &quot;file://c:\Users\Tommy\Documents\Visual Studio 2008\Projects\test\test\Debug\BuildLog.htm&quot;
1&gt;test - 2 error(s), 2 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
</code></pre>
<p>Der Code der diesen Fehler erzeugt hat sieht so aus:</p>
<pre><code class="language-cpp">my::TMatrix &lt;size_t, 2, 2, char&gt; eins;
eins[0][0] = 2;
eins[0][1] = 0;
eins[1][1] = 1;

float det = my::math::Determinant_LaPlace &lt;float&gt; (eins);
</code></pre>
<p>Wie bekomm ich es hin, dass mein Compiler merkt, dass er das template nicht für eine negative anzahl an zeilen/spalten erzeugen soll?<br />
Oder geht das nicht mal eben mit ner anderen Schreibweise?</p>
<p>Würder ihr die Dimensionen überhaupt über Templates lösen oder etwa erst zur Laufzeit ermitteln (was ja Probleme bei sämtlichen Operatoren mit sich bringen würde: Bsp.: Addition 2er Matrizen, Determinante, Vergleiche, ...)</p>
<p>Danke schon mal : &gt;</p>
<p>PS: Bitte keine Vorschläge statt des Pointers einen STL-Container oder ein Array auf dem Stack zu nehmen (was ja das Problem auch nicht behebt) - da die Stack-Größe eines Prozesses sehr stark (zumindest im Vergleich zum Heap) begrentzt ist, möchte ich mir dadurch keine Obergrenze setzen - so weit ich weiß speichert auch std::tr1::array seinen Inhalt auf dem Stack, oder?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1630570</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1630570</guid><dc:creator><![CDATA[unskilled]]></dc:creator><pubDate>Mon, 15 Dec 2008 01:03:35 GMT</pubDate></item><item><title><![CDATA[Reply to Templates und deren Grenzen on Mon, 15 Dec 2008 02:58:05 GMT]]></title><description><![CDATA[<p>Viel zu viel Code, viel zu komplex beschrieben und die Lösung ist doch so einfach (wenn ich das Problem jetzt richtig verstanden habe :)).<br />
Verändere deine LaPlace Funktion auf diese Weise:</p>
<pre><code class="language-cpp">template &lt;typename Treturnvaluetype, std::size_t dim, typename Tvaluetype&gt;
Treturnvaluetype Determinant_LaPlace (const TMatrix &lt;dim, dim, Tvaluetype&gt; &amp;thismatrix)
{
    Treturnvaluetype sum = Treturnvaluetype();
    const std::size_t nextdim (dim-1);

    typedef TMatrix &lt;dim, dim, Tvaluetype&gt; TThisMatrix;
    typedef TMatrix &lt;nextdim, nextdim, Tvaluetype&gt; TNextMatrix;

    TNextMatrix nextmatrix;

    for (Tsizetype m = Tsizetype(); m != nextdim; ++m)
    {
        for (Tsizetype n = Tsizetype(); n != nextdim; ++n)
        {
            TNextMatrix::Line &amp;line_to = nextmatrix[n];
            const TThisMatrix::Line &amp;line_from = thismatrix[n+1];

            for (Tsizetype i = Tsizetype(); i != n; ++i)
            {
                line_to[i] = line_from[i];
            }
            for (Tsizetype i (n); i != nextdim; ++i)
            {
                line_to[i] = line_from[i+1];
            }
        }
        sum += thismatrix[0][m] * Determinant_LaPlace &lt;Treturnvaluetype&gt; (nextmatrix);
    }

    return sum;
}

// Und jetzt Spezialisierungen:
template &lt;typename Treturnvaluetype, typename Tvaluetype&gt;
Treturnvaluetype Determinant_LaPlace&lt;Treturnvaluetype, 2, Tvaluetype&gt; (const TMatrix &lt;2, 2, Tvaluetype&gt; &amp;thismatrix)
{
    return Treturnvaluetype(thismatrix[0][0] * thismatrix[1][1] - thismatrix[0][1] * thismatrix[1][0]);
}

template&lt;typename Treturnvaluetype, typename Tvaluetype&gt;
Treturnvaluetype Determinant_LaPlace&lt;Treturnvaluetype, 1, Tvaluetype&gt; (const TMatrix &lt;1, 1, Tvaluetype&gt; &amp;thismatrix)
{
    throw std::invalid_argument (&quot;Dimension needs to be bigger then one&quot;);
    // Könnte man natürlich auch ein static_assert(false) machen ;)
}

template&lt;typename Treturnvaluetype, typename Tvaluetype&gt;
Treturnvaluetype Determinant_LaPlace&lt;Treturnvaluetype, 0, Tvaluetype&gt; (const TMatrix &lt;0, 0, Tvaluetype&gt; &amp;thismatrix)
{
    throw std::invalid_argument (&quot;Dimension needs to be bigger then one&quot;);
    // Könnte man natürlich auch ein static_assert(false) machen ;)
}
</code></pre>
<p>Man, hast du eine hässliche schreibweise ... <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f603.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--grinning_face_with_big_eyes"
      title=":D"
      alt="😃"
    /><br />
Übrigens, was soll dieses <code>Tsizetype</code> ? Habe das gleich mal rausgenommen, ist doch völlig überflüssig. Nimm gleich einen <code>std::size_t</code> , man hat ja keinen Vorteil, wenn man das immer selber angeben muss.</p>
<p>Kurz vielleicht noch zusammengefasst, was ich getan habe und wieso:<br />
Ich habe deine if-else if-else Anweisung auseinander genommen. Templates haben etwas blödes an sich, sie werden immer instanziert, auch wenn man sie vielleicht gar nicht braucht. Also obwohl dim &lt; 3 gewesen ist, so wurde trotzdem die Matrix mit der Dimension dim - 1 instanziert. Bei dim == 0, bekommen wir ein dim - 1 = -1, was natürlich zu einem Fehler beim Array führt. Um sowas zu verhindern, muss man eben Spezialisierungen einführen. Diese Spezialisierungen halten den rekursiven Fortschritt der Templates auf. So lassen sich mit den Templates übrigens auch Schleifen erzeugen <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>Habe den Code selber nicht getestet und bin auch etwas müde, daher könnte sich gut ein Fehler eingeschlichen haben. Aber ich hoffe die Fehlerbegründung kam an und du hast es verstanden.</p>
<p>Grüssli</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1630578</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1630578</guid><dc:creator><![CDATA[Dravere]]></dc:creator><pubDate>Mon, 15 Dec 2008 02:58:05 GMT</pubDate></item><item><title><![CDATA[Reply to Templates und deren Grenzen on Mon, 15 Dec 2008 13:24:22 GMT]]></title><description><![CDATA[<p>Danke - an Spezialisierungen hatte ich nat nicht gedacht <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f61e.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--disappointed_face"
      title=":("
      alt="😞"
    /> Weiß zwar, dass man das so machen kann aber es war mir einfach zu viel Arbeit und ich dachte, dass es keinen Vorteil hat, aber ok - jz erscheints mir auch logisch <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=";D"
      alt="😉"
    /><br />
Naja - bekannterweise geht size_t ja auf 32bit OS`s auch nur bis 2^32-1 - falls aber eine dimension größer werden sollte würde das ein wenig schwerer werden (mal abgesehen davon, dass so ne Matrizen-Operationen dann auch nicht mehr allzu schnell bearbeitet werden können, aber das is ja erstmal 2. ^^)</p>
<p>bye</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1630778</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1630778</guid><dc:creator><![CDATA[unskilled]]></dc:creator><pubDate>Mon, 15 Dec 2008 13:24:22 GMT</pubDate></item><item><title><![CDATA[Reply to Templates und deren Grenzen on Mon, 15 Dec 2008 13:47:06 GMT]]></title><description><![CDATA[<p>Naja, wenn du dir überlegst, dass der <code>operator new</code> und <code>new[]</code> einen <code>std::size_t</code> Parameter für die Grösse erwarten und auch das <code>sizeof</code> Schlüsselwort eine Konstante vom Typ <code>std::size_t</code> zurück gibt, dann wäre das wohl schon der richtige Typ. Ein Array kann dann wohl nur schlecht grösser sein, als ein <code>std::size_t</code> aktzeptiert:</p>
<pre><code class="language-cpp">char arr[xxxx];
sizeof(arr); // &lt;- gibt einen std::size_t zurück,
             //    die Zahl xxxx muss also in einen std::size_t reinpassen.
</code></pre>
<p>Und wie du auch selbst sagst, eine Matrix der Grösse 2^32-1 dürfte ein wenig gross sein <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="😉"
    /><br />
Du machst mit dem zusätzlichen Templateparameter dem Nutzer einfach zusätzliche Arbeit.</p>
<p>Grüssli</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1630785</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1630785</guid><dc:creator><![CDATA[Dravere]]></dc:creator><pubDate>Mon, 15 Dec 2008 13:47:06 GMT</pubDate></item><item><title><![CDATA[Reply to Templates und deren Grenzen on Mon, 15 Dec 2008 15:13:19 GMT]]></title><description><![CDATA[<p>hmm... ok ^^</p>
<p>edit: Der Vollständigkeit halber hier mal die richtige Version (die von oben war ein wenig sehr fehlerbehaftet, aber naja <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f603.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--grinning_face_with_big_eyes"
      title=":D"
      alt="😃"
    /> )</p>
<pre><code class="language-cpp">template &lt;typename Treturnvaluetype, size_t dim, typename Tvaluetype&gt;
Treturnvaluetype Determinant_LaPlace (const TMatrix &lt;dim, dim, Tvaluetype&gt; &amp;thismatrix)
{
	Treturnvaluetype sum = Treturnvaluetype();
	typedef TMatrix &lt;dim, dim, Tvaluetype&gt;	TThisMatrix;
	typedef typename TThisMatrix::SizeType	SizeType;
	const SizeType nextdim (dim-1);
	typedef TMatrix &lt;nextdim, nextdim, Tvaluetype&gt; TNextMatrix;

	TNextMatrix nextmatrix;

	for (SizeType m = SizeType(); m != dim; ++m)
	{
		for (SizeType n = SizeType(); n != nextdim; ++n)
		{
			TNextMatrix::Line &amp;line_to = nextmatrix[n];
			const TThisMatrix::Line &amp;line_from = thismatrix[n+1];

			for (SizeType i = SizeType(); i != m; ++i)
			{
				line_to[i] = line_from[i];
			}
			for (SizeType i (m); i != nextdim; ++i)
			{
				line_to[i] = line_from[i+1];
			}
		}
		if (m%2)
			sum -= thismatrix[0][m] * Determinant_LaPlace &lt;Treturnvaluetype&gt; (nextmatrix);
		else
			sum += thismatrix[0][m] * Determinant_LaPlace &lt;Treturnvaluetype&gt; (nextmatrix);
	}
	return sum;
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1630789</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1630789</guid><dc:creator><![CDATA[unskilled]]></dc:creator><pubDate>Mon, 15 Dec 2008 15:13:19 GMT</pubDate></item><item><title><![CDATA[Reply to Templates und deren Grenzen on Mon, 15 Dec 2008 16:06:00 GMT]]></title><description><![CDATA[<p>a) Es gibt die Determinante einer 1x1-Matrix, nämlich das einzelne Element selbst. Also nix invalid_argument.<br />
b) Ich würde durchaus statische Arrays einsetzen, du kannst ja eine Instanz der Klasse auf dem Heap erstellen, dann ist der Stack garnicht bis kaum gewachsen. Mit smart pointern ist die Speicherverwaltung keine große Sache. Also auch keine Obergrenze dadurch. Aber ist nicht zwingend notwendig, ich bin mir sicher, dass es bezogen auf Speicher und Geschwindigkeit sowohl Vorteile als auch Nachteile gibt. Z.B. macht shared_ptr eingesparte dynamische Allokationen wieder zunichte. Für jede Zeile eine dynamische Allokation zu machen ist aber unnötig, du kannst alles am Block allozieren!<br />
c) Für riesige Matrizen ist diese Klasse sowieso nicht geeignet, das hätte gigantischen Speicherverbrauch zur Folge. Dafür gibt es spezielle Implementationen für große Matrizen mit vielen Nullen oder gleichen Elementen usw. Schau dir einfach mal boost::ublas an.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1630863</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1630863</guid><dc:creator><![CDATA[geloescht]]></dc:creator><pubDate>Mon, 15 Dec 2008 16:06:00 GMT</pubDate></item><item><title><![CDATA[Reply to Templates und deren Grenzen on Mon, 15 Dec 2008 16:46:38 GMT]]></title><description><![CDATA[<p>geloescht schrieb:</p>
<blockquote>
<p>a) Es gibt die Determinante einer 1x1-Matrix, nämlich das einzelne Element selbst. Also nix invalid_argument.</p>
</blockquote>
<p>Japp, hab ich (jz) auch so</p>
<p>geloescht schrieb:</p>
<blockquote>
<p>Ich würde durchaus statische Arrays einsetzen, du kannst ja eine Instanz der Klasse auf dem Heap erstellen, dann ist der Stack garnicht bis kaum gewachsen. Mit smart pointern ist die Speicherverwaltung keine große Sache. Also auch keine Obergrenze dadurch. Aber ist nicht zwingend notwendig, ich bin mir sicher, dass es bezogen auf Speicher und Geschwindigkeit sowohl Vorteile als auch Nachteile gibt. Z.B. macht shared_ptr eingesparte dynamische Allokationen wieder zunichte. Für jede Zeile eine dynamische Allokation zu machen ist aber unnötig, du kannst alles am Block allozieren!</p>
</blockquote>
<p>Ich alloziere alles im Block - und mach danach nen placement new auf den Eintrag um ihn mit 0 oder was auch immer zu initialisieren</p>
<p>geloescht schrieb:</p>
<blockquote>
<p>Für riesige Matrizen ist diese Klasse sowieso nicht geeignet, das hätte gigantischen Speicherverbrauch zur Folge. Dafür gibt es spezielle Implementationen für große Matrizen mit vielen Nullen oder gleichen Elementen usw. Schau dir einfach mal boost::ublas an.</p>
</blockquote>
<p>Diese Klasse soll aber nicht für schwach besetzte Matrizen sein - sonst hätte ich sie kaum TMatrix genannt sondern iwie vermerkt, dass sie besser mit schwach besetzten Matrizen umgehen kann als mit voll besetzten...</p>
<p>Noch mal dazu:</p>
<blockquote>
<p>Mit smart pointern ist die Speicherverwaltung keine große Sache</p>
</blockquote>
<p>mit new und delete ja auch nicht, weil ich einmal den Speicher alloziere und einmal lösche - dann ist es noch in der copy-Fkt ein bisschen mehr Arbeit, aber alles in allem sind es vll 10 Zeilen die ich mir dadurch sparen könnte - Vorteile sehe ich davon aber keine - Nachteile würden mir aber ein paar einfallen - angefangen damit, dass ich nicht so schön mit dem Inhalt spielen kann, wie ich es mit den rohen Arrays tun kann ^^</p>
<p>bb <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/1630874</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1630874</guid><dc:creator><![CDATA[unskilled]]></dc:creator><pubDate>Mon, 15 Dec 2008 16:46:38 GMT</pubDate></item><item><title><![CDATA[Reply to Templates und deren Grenzen on Mon, 15 Dec 2008 21:04:21 GMT]]></title><description><![CDATA[<p>Wieso verwendest du eigentlich kein <code>std::tr1::array</code> (oder bei fehlender TR1-Unterstützung <code>boost::array</code> )?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1630988</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1630988</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Mon, 15 Dec 2008 21:04:21 GMT</pubDate></item><item><title><![CDATA[Reply to Templates und deren Grenzen on Mon, 15 Dec 2008 21:16:55 GMT]]></title><description><![CDATA[<p>Nexus schrieb:</p>
<blockquote>
<p>Wieso verwendest du eigentlich kein <code>std::tr1::array</code> (oder bei fehlender TR1-Unterstützung <code>boost::array</code> )?</p>
</blockquote>
<p>unskilled schrieb:</p>
<blockquote>
<p>so weit ich weiß speichert auch std::tr1::array seinen Inhalt auf dem Stack, oder?</p>
</blockquote>
<p>Da std::tr1::array meines Erachtens nach auf dem Stack operiert (was zwar schneller ist aber der ist eben auch sehr begrentzt...)<br />
Außerdem glaube ich nicht, dass ich mit std::tr1::array so gut arbeiten kann, wie bis jetzt:</p>
<pre><code class="language-cpp">Line(ValueType fill_with = ValueType())
	:	values(new ValueType[row_count])
{
	for(SizeType i = SizeType(); i != row_count; ++i)
	{
		new (values + i) ValueType(fill_with);
	}
}

//bzw.

TMatrix(ValueType fill_with = ValueType())
	:	lines ((Line*) new char[sizeof(Line) * line_count])
{
	for(SizeType i = SizeType(); i != line_count; ++i)
	{
		new (lines + i) Line(fill_with);
	}
}
</code></pre>
<p>Und da es so auch geht und ich nicht weiß, ob (wenn ja, wie) es mit std::tr1::array geht, habe ich eben diese Lösung gewählt ^^ Oder ist gegen diese Variante irgendetwas zu sagen?</p>
<p>bb</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1630996</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1630996</guid><dc:creator><![CDATA[unskilled]]></dc:creator><pubDate>Mon, 15 Dec 2008 21:16:55 GMT</pubDate></item><item><title><![CDATA[Reply to Templates und deren Grenzen on Mon, 15 Dec 2008 21:22:01 GMT]]></title><description><![CDATA[<p>Sorry, das hab ich nicht gesehen. Ja, <code>std::tr1::array</code> ist ein einfacher Wrapper für C-Arrays, der noch weitere Funktionalität bereitstellt.</p>
<p>unskilled schrieb:</p>
<blockquote>
<p>Oder ist gegen diese Variante irgendetwas zu sagen?</p>
</blockquote>
<p>Findest du das schön? <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>
<pre><code class="language-cpp">lines ((Line*) new char[sizeof(Line) * line_count])
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1631001</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1631001</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Mon, 15 Dec 2008 21:22:01 GMT</pubDate></item><item><title><![CDATA[Reply to Templates und deren Grenzen on Mon, 15 Dec 2008 21:29:59 GMT]]></title><description><![CDATA[<p>Nexus schrieb:</p>
<blockquote>
<p>Ja, std::tr1::array ist ein einfacher Wrapper für C-Arrays, der noch weitere Funktionalität bereitstellt</p>
</blockquote>
<p>Gut - ich hatte daran gezweifelt, dass er auch bei großen Größen auf dem Stack bleibt (hätte ja sein können, dass es je nach Größe spezialisiert ist)...</p>
<p>Nexus schrieb:</p>
<blockquote>
<p>Findest du das schön? <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>
<pre><code class="language-cpp">lines ((Line*) new char[sizeof(Line) * line_count])
</code></pre>
</blockquote>
<p>Hältst du es für umgänglich? (extrem hübsch finde ich es zwar nicht aber ich hab keinen anderen Weg gefunden und außer den optischen Nachteil ist mir keiner aufgefallen - und wenn an mal 5 Sekunden Zeit investiert erkennt man auch als Außenstehender, was man dort macht)</p>
<p>bb</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1631005</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1631005</guid><dc:creator><![CDATA[unskilled]]></dc:creator><pubDate>Mon, 15 Dec 2008 21:29:59 GMT</pubDate></item><item><title><![CDATA[Reply to Templates und deren Grenzen on Tue, 16 Dec 2008 10:36:24 GMT]]></title><description><![CDATA[<p>Schön, dass du diese kleine Änderungen mit der Determinante gemacht hast - in deinem Originalpost war kein placement new zu sehen. Ich fürchte aber, dass es die Arbeit nicht wert ist, die dir ein statisches Array sparen würde. Vll. hab ich mich falsch ausgedrückt: Mit &quot;statisches Array&quot; meine ich, dass die Größe des Arrays zu Compilezeit feststeht, nicht darauf, ob das Array auf dem Heap, dem Stack oder sonstwo gespeichert ist. Du könntest eine Instanz von std::tr1::array immernoch auf dem Heap erstellen! Plus es ist leicht damit umzugehen plus es ist schnell plus es spart Speicherplatz ggü. einem std::vector plus es ist einfach kopierbar.<br />
Ein Beispiel:</p>
<pre><code class="language-cpp">template &lt;int size&gt;
struct giant
{
  char bar[size];
};

int main()
{
  //Das da braucht gerademal nen Pointer auf dem Stack
  giant* A = new giant&lt;1000&gt;();
  //Das da braucht womöglich 1kB auf dem Stack
  giant B&lt;1000&gt;;
}
</code></pre>
<p>Über die Grenzen des Stacks brauchst du dir wohl erst Gedanken machen, wenn du auf sie stößt.<br />
:xmas2:</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1631147</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1631147</guid><dc:creator><![CDATA[geloescht]]></dc:creator><pubDate>Tue, 16 Dec 2008 10:36:24 GMT</pubDate></item><item><title><![CDATA[Reply to Templates und deren Grenzen on Tue, 16 Dec 2008 19:13:34 GMT]]></title><description><![CDATA[<p>unskilled schrieb:</p>
<blockquote>
<p>Nexus schrieb:</p>
<blockquote>
<p>Findest du das schön? <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>
<pre><code class="language-cpp">lines ((Line*) new char[sizeof(Line) * line_count])
</code></pre>
</blockquote>
<p>Hältst du es für umgänglich? (extrem hübsch finde ich es zwar nicht aber ich hab keinen anderen Weg gefunden und außer den optischen Nachteil ist mir keiner aufgefallen - und wenn an mal 5 Sekunden Zeit investiert erkennt man auch als Außenstehender, was man dort macht)</p>
</blockquote>
<p>Aber was war dann mit deiner vorherigen Lösung?</p>
<pre><code class="language-cpp">lines(new Line[line_count])
</code></pre>
<p>geloescht schrieb:</p>
<blockquote>
<p>Du könntest eine Instanz von std::tr1::array immernoch auf dem Heap erstellen! Plus es ist leicht damit umzugehen <strong>plus es ist schnell</strong> plus es spart Speicherplatz ggü. einem std::vector plus es ist einfach kopierbar.</p>
</blockquote>
<p>Die Schnelligkeit, die aufgrund der Stack-Allokation gewonnen wird, geht hier auch wieder verloren. Ein <code>std::tr1::array</code> auf dem Heap dürfte etwa gleich schnell sein wie ein <code>std::vector</code> . Und der verschwendete Speicherplatz sollte eigentlich auch nicht gross ins Gewicht fallen. Aber darüber sollte man sich sowieso erst Gedanken machen, wenn es erforderlich ist...</p>
<p>Im Gegenzug nimmt man mit einem dynamisch allokierten <code>std::tr1::array</code> manuelle Speicherverwaltung und die damit verbundenen Probleme in Kauf. Ich selbst würde <code>std::tr1::array</code> wirklich nur für statische Arrays verwenden.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1631458</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1631458</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Tue, 16 Dec 2008 19:13:34 GMT</pubDate></item><item><title><![CDATA[Reply to Templates und deren Grenzen on Wed, 17 Dec 2008 01:38:23 GMT]]></title><description><![CDATA[<p>Nexus schrieb:</p>
<blockquote>
<p>unskilled schrieb:</p>
<blockquote>
<p>Nexus schrieb:</p>
<blockquote>
<p>Aber was war dann mit deiner vorherigen Lösung?</p>
<pre><code class="language-cpp">lines(new Line[line_count])
</code></pre>
</blockquote>
</blockquote>
</blockquote>
<p>(boar - was ne Arbeit das alles fertig auszuzitieren ^^)<br />
Hmm... Ist natürlich ne sehr gute Frage, wieso ich das gemacht habe - eigtl weil ich es für nötig hielt - allerdings kann ich dir weder sagen, warum ich das getan habe, noch hab ich jetzt beim Ändern auf die schönere Variante Fehlermeldungen erhalten.</p>
<p>Nur einwas ist sehr komisch:<br />
main</p>
<pre><code class="language-cpp">{ //~0 KB
	my::TMatrix &lt;1000, 1000, double&gt; eins(23); //~n KB
} //~n/2 KB
</code></pre>
<p>(ich weiß, das OS nimmt nicht sofort wieder allen Speicher zurück etc - aber bei jeder Größe hat mein Programm nach dem Ende des Scopes immer noch die Hälfte des RAMs (priv. Arbeitssatz) wie im Scope...</p>
<p>counter</p>
<pre><code class="language-cpp">namespace my
{
	size_t v (0);
	size_t l (0);
	size_t v2 (0);
}
</code></pre>
<pre><code>vor dem erstellen:
0
0
0

nach dem erstellen:
2000
1
1000

nach dem zerstören:
1000
0
0
</code></pre>
<p>//matrix -&gt; matrix</p>
<pre><code class="language-cpp">TMatrix(ValueType fill_with = ValueType())
	:	lines (new Line[line_count])
{
	++::my::l;
	for(SizeType i = SizeType(); i != line_count; ++i)
	{
		new (lines + i) Line(fill_with);
	}
	::my::v2 += line_count;
}

~TMatrix()
{
	--::my::l;
	::my::v2 -= line_count;
	delete [] lines;
}
</code></pre>
<p>matrix -&gt; line</p>
<pre><code class="language-cpp">Line(ValueType fill_with = ValueType())
	:	values(new ValueType[row_count])
{
	++::my::v;
	for(SizeType i = SizeType(); i != row_count; ++i)
	{
		new (values + i) ValueType(fill_with);
	}
}
~Line()
{
	--::my::v;
	delete []values;
}
</code></pre>
<p>Nun erscheint mir ein nach char* casten im ctor doch wieder sinnvoll - allerdings wird dann der dtor ja trotzdem nicht aufgerufen - geht ein placement new überhaupt auf eine struktur, die selbst im ctor werte initialisiert? Oder gibts zum placement new irgend nen Gegenstück, was ich kennen sollte?</p>
<p>Danke schon mal - bb</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1631570</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1631570</guid><dc:creator><![CDATA[unskilled]]></dc:creator><pubDate>Wed, 17 Dec 2008 01:38:23 GMT</pubDate></item><item><title><![CDATA[Reply to Templates und deren Grenzen on Wed, 17 Dec 2008 05:58:21 GMT]]></title><description><![CDATA[<p>Zwei Anmerkungen zu der initialisierung von lines in der Initliste:</p>
<ol>
<li>Ist die Variante mit dem new char... nicht nur unschön, sie müsste sogar wenn mans genau nimmt noch unschöner sein - aus C-Cast mach reinterpret_cast</li>
<li>ist die Variante dann nicht nur noch unschöner, sondern es müsste eigentlich, getriggert durch den reinterpret_cast auf ein Array, folgendes passieren: sämtliche Alamrglocken schrillen und es blinkt ein großes, grelles Schild mit der Aufschrift &quot;alignment/padding?!&quot;</li>
<li>Die neue Variante ist zwar schöner anzusehn, aber nicht exception-safe (falls das für dich von Bedeutung ist): Wenn irgendwo im Rest der init-Liste eine Exception hochkommt dann hat das Objekt selbst nie existiert, weil nie alle Member initialisiert wurden, und alles was bleibt nachdem die bereits initialisierten Objekte abgeräumt wurden ist ein Speicherleck. Also kein new in Init-Listen, wenn man Exception safe bleiben möchte (es sei denn man initialisiert damit einen Smartpointer, dessen entsprechender Konstruktor unter Garantie keine Exceptions wirft.)</li>
</ol>
]]></description><link>https://www.c-plusplus.net/forum/post/1631588</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1631588</guid><dc:creator><![CDATA[pumuckl]]></dc:creator><pubDate>Wed, 17 Dec 2008 05:58:21 GMT</pubDate></item><item><title><![CDATA[Reply to Templates und deren Grenzen on Wed, 17 Dec 2008 20:39:51 GMT]]></title><description><![CDATA[<p>pumuckl schrieb:</p>
<blockquote>
<ol>
<li>Ist die Variante mit dem new char... nicht nur unschön, sie müsste sogar wenn mans genau nimmt noch unschöner sein - aus C-Cast mach reinterpret_cast</li>
</ol>
</blockquote>
<p>Jopp - das wärs schon noch geworden, aber wollte ja erst mal wissen, ob es von der theorie so richtig wäre</p>
<p>pumuckl schrieb:</p>
<blockquote>
<ol start="2">
<li>ist die Variante dann nicht nur noch unschöner, sondern es müsste eigentlich, getriggert durch den reinterpret_cast auf ein Array, folgendes passieren: sämtliche Alamrglocken schrillen und es blinkt ein großes, grelles Schild mit der Aufschrift &quot;alignment/padding?!&quot;</li>
</ol>
</blockquote>
<p>Oh - daran hatte ich wirklich nicht gedacht - aber habs ja jz auch wieder mit nem &quot;sauberen&quot; new und placement new - aber das speicherleck bleibt bestehen - und ich weiß nicht, warum -.-</p>
<p>pumuckl schrieb:</p>
<blockquote>
<ol start="3">
<li>Die neue Variante ist zwar schöner anzusehn, aber nicht exception-safe (falls das für dich von Bedeutung ist): Wenn irgendwo im Rest der init-Liste eine Exception hochkommt dann hat das Objekt selbst nie existiert, weil nie alle Member initialisiert wurden, und alles was bleibt nachdem die bereits initialisierten Objekte abgeräumt wurden ist ein Speicherleck. Also kein new in Init-Listen, wenn man Exception safe bleiben möchte (es sei denn man initialisiert damit einen Smartpointer, dessen entsprechender Konstruktor unter Garantie keine Exceptions wirft.)</li>
</ol>
</blockquote>
<p>Also pack ich nen try / catch um die schleife und fange bad_alloc auf - und falls es geworfen wurde, führe ich den dtor aus und werfe die exception einfach ganz normal weiter?!</p>
<p>bb</p>
<p>edit: Also vll weiß ichs auch einfach nicht, aber ich glaube das normale new darf gar kein new auf Line sein sondern _muss_ auf nen intergralen Typen sein?!<br />
Meine Lösung sieht jetzt folgendermaßen aus<br />
(ich weiß nicht, ob man den exception-safe ctor normalerweise ähnlich implementiert aber ich hab anscheind noch irgendwo nen fehler drin - jedenfalls gibt er bei nem bad_alloc anscheind nicht wieder alles frei &gt;&lt;</p>
<p>Minimal-Code (fertig für copy&amp;paste ^^):</p>
<pre><code class="language-cpp">template &lt;size_t line_count, size_t row_count, typename ValueType&gt;
class TMatrix
{
public:
	typedef size_t					SizeType;

	class Line
	{
	private:
		ValueType *values;

		void destruct(SizeType i = row_count) throw()
		{
			if(!values)
				return;

			for(; i != 0; --i)
			{
				values[i-1].~ValueType();
			}
			delete [] values;
			values = nullptr;
		}
	public:
		Line(ValueType fill_with = ValueType())
			:	values(new ValueType[row_count])
		{
			SizeType i = SizeType();
			try
			{
				for(; i != row_count; ++i)
				{
					new (values + i) ValueType(fill_with);
				}
			}
			catch (...)
			{
				destruct(i);
				throw;
			}
		}

		~Line()
		{
			destruct();
		}
	};

private:
	Line *lines;

	void destruct(SizeType i = line_count) throw()
	{
		if(!lines)
			return;

		for(; i != 0; --i)
		{
			lines[i-1].~Line();
		}
		delete [] reinterpret_cast &lt;char*&gt; (lines);
		lines = nullptr;
	}

public:
	TMatrix(ValueType fill_with = ValueType())
		:	lines ( reinterpret_cast &lt;Line*&gt; (new char[sizeof(Line) * line_count]) )
	{
		SizeType i = SizeType();
		try
		{
			for(; i != line_count; ++i)
			{
				new (lines + i) Line(fill_with);
			}
		}
		catch(...)
		{
			destruct(i);
			throw;
		}
	}

	~TMatrix()
	{
		destruct();
	}
};
</code></pre>
<p>Nun könnte man aus destruct noch nen template machen und wahrscheinlich auch noch nen template für init oder so - aber im Grunde genommen sollte es doch so (oder ähnlich) gehen, oder?</p>
<p>Zu <strong>Alignment/Padding</strong>: Sicher, dass das hier eine Rolle spielt?</p>
<p>bb und danke schon mal fürs angucken?! : &gt;</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1631997</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1631997</guid><dc:creator><![CDATA[unskilled]]></dc:creator><pubDate>Wed, 17 Dec 2008 20:39:51 GMT</pubDate></item><item><title><![CDATA[Reply to Templates und deren Grenzen on Wed, 17 Dec 2008 21:12:53 GMT]]></title><description><![CDATA[<p>Dravere schrieb:</p>
<blockquote>
<pre><code class="language-cpp">// Und jetzt Spezialisierungen:
template &lt;typename Treturnvaluetype, typename Tvaluetype&gt;
Treturnvaluetype Determinant_LaPlace&lt;Treturnvaluetype, 2, Tvaluetype&gt; (const TMatrix &lt;2, 2, Tvaluetype&gt; &amp;thismatrix)
{
    return Treturnvaluetype(thismatrix[0][0] * thismatrix[1][1] - thismatrix[0][1] * thismatrix[1][0]);
}
// ...
</code></pre>
</blockquote>
<p>Leider sind partielle Spezialisierungen von Funktionstemplates nicht erlaubt, oder kompiliert das dein Compiler ?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1632113</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1632113</guid><dc:creator><![CDATA[[[global:guest]]]]></dc:creator><pubDate>Wed, 17 Dec 2008 21:12:53 GMT</pubDate></item><item><title><![CDATA[Reply to Templates und deren Grenzen on Wed, 17 Dec 2008 21:28:30 GMT]]></title><description><![CDATA[<p>*mist*</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1632126</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1632126</guid><dc:creator><![CDATA[drakon]]></dc:creator><pubDate>Wed, 17 Dec 2008 21:28:30 GMT</pubDate></item><item><title><![CDATA[Reply to Templates und deren Grenzen on Wed, 17 Dec 2008 21:28:39 GMT]]></title><description><![CDATA[<p>KasF schrieb:</p>
<blockquote>
<p>Leider sind partielle Spezialisierungen von Funktionstemplates nicht erlaubt, oder kompiliert das dein Compiler ?</p>
</blockquote>
<p>Jap, tut er. Zwar habe ich jetzt nicht genau das gemacht, aber habe ein foo-Test gemacht:</p>
<pre><code class="language-cpp">#include &quot;Test.hpp&quot;

#include &lt;iostream&gt;

template&lt;typename T&gt;
void foo()
{
	std::cout &lt;&lt; &quot;T!&quot; &lt;&lt; std::endl;
}

template&lt;&gt;
void foo&lt;void&gt;()
{
	std::cout &lt;&lt; &quot;void&quot; &lt;&lt; std::endl;
}

int main()
{
	foo&lt;int&gt;();
	foo&lt;void&gt;();

	test::wait(&quot;Press ENTER to exit...&quot;);

	return 0;
}
</code></pre>
<p>Mir persönlich ist der genaue Standard dazu nicht bekannt. Verwende den MSVC 2005.</p>
<p>Aber was soll, dann nimmt man statt Templatespezialisierung Funktionsüberladung. Sollte genauso gehen.</p>
<p>Grüssli</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1632127</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1632127</guid><dc:creator><![CDATA[Dravere]]></dc:creator><pubDate>Wed, 17 Dec 2008 21:28:39 GMT</pubDate></item><item><title><![CDATA[Reply to Templates und deren Grenzen on Wed, 17 Dec 2008 21:34:35 GMT]]></title><description><![CDATA[<p>Das entscheidende war, dass du dort eben partielle Spezialisierung benutzt hast. Komplette Spezialisierung ist erlaubt, partielle eben nicht..</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1632130</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1632130</guid><dc:creator><![CDATA[drakon]]></dc:creator><pubDate>Wed, 17 Dec 2008 21:34:35 GMT</pubDate></item><item><title><![CDATA[Reply to Templates und deren Grenzen on Wed, 17 Dec 2008 21:48:58 GMT]]></title><description><![CDATA[<p>drakon schrieb:</p>
<blockquote>
<p>Das entscheidende war, dass du dort eben partielle Spezialisierung benutzt hast. Komplette Spezialisierung ist erlaubt, partielle eben nicht..</p>
</blockquote>
<p>Achso ... *Kopf -&gt; Tisch*<br />
Das kommt ja auch erst mit dem nächsten Standard <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>
<p>Naja, aber in diesem Fall sollten Funktionsüberladungen Abhilfe schaffen.</p>
<p>Grüssli</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1632140</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1632140</guid><dc:creator><![CDATA[Dravere]]></dc:creator><pubDate>Wed, 17 Dec 2008 21:48:58 GMT</pubDate></item><item><title><![CDATA[Reply to Templates und deren Grenzen on Wed, 17 Dec 2008 21:53:46 GMT]]></title><description><![CDATA[<p>Dravere schrieb:</p>
<blockquote>
<p>Das kommt ja auch erst mit dem nächsten Standard <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>
</blockquote>
<p>Sind in C++0x partielle Spezialisierungen von Funktionen möglich? Was war der Grund, sie bisher nicht einzuführen?</p>
<p>Dravere schrieb:</p>
<blockquote>
<p>*Kopf -&gt; Tisch*</p>
</blockquote>
<p>Hehe, als ich das zuerst gesehen habe, dachte ich, es handle sich um eine Dereferenzierung. Dann hat mich verwirrt, dass bei &quot;Tisch&quot; das * nach dem Bezeichner steht... Vielleicht sollte ich langsam ins Bett... <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f603.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--grinning_face_with_big_eyes"
      title=":D"
      alt="😃"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/1632147</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1632147</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Wed, 17 Dec 2008 21:53:46 GMT</pubDate></item><item><title><![CDATA[Reply to Templates und deren Grenzen on Wed, 17 Dec 2008 21:56:26 GMT]]></title><description><![CDATA[<p>Dravere schrieb:</p>
<blockquote>
<p>drakon schrieb:</p>
<blockquote>
<p>Das entscheidende war, dass du dort eben partielle Spezialisierung benutzt hast. Komplette Spezialisierung ist erlaubt, partielle eben nicht..</p>
</blockquote>
<p>Achso ... *Kopf -&gt; Tisch*<br />
Das kommt ja auch erst mit dem nächsten Standard <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>
<p>Naja, aber in diesem Fall sollten Funktionsüberladungen Abhilfe schaffen.</p>
<p>Grüssli</p>
</blockquote>
<p>Hehe..</p>
<p>Wenn wir schon bei dabei sind..</p>
<p>Das dürfte für dich interessant sein (warst doch du,der Probleme hatte, oder?:))<br />
<a href="http://developer.amd.com/documentation/videos/pages/IntroductiontoAMDCodeAnalystPerformanceAnalyzer.aspx" rel="nofollow">http://developer.amd.com/documentation/videos/pages/IntroductiontoAMDCodeAnalystPerformanceAnalyzer.aspx</a></p>
<p>(Achtung lautes Video.. -.-)</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1632149</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1632149</guid><dc:creator><![CDATA[drakon]]></dc:creator><pubDate>Wed, 17 Dec 2008 21:56:26 GMT</pubDate></item><item><title><![CDATA[Reply to Templates und deren Grenzen on Wed, 17 Dec 2008 22:00:06 GMT]]></title><description><![CDATA[<p>Nexus schrieb:</p>
<blockquote>
<p>Dravere schrieb:</p>
<blockquote>
<p>Das kommt ja auch erst mit dem nächsten Standard <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>
</blockquote>
<p>Sind in C++0x partielle Spezialisierungen von Funktionen möglich? Was war der Grund, sie bisher nicht einzuführen?</p>
</blockquote>
<p>Ich dachte ich hätte mal sowas gehört. Aber kann es grad nicht finden im letzten Draft. Aber das Zeug finde ich teilweise sowieso etwas komplex beschrieben <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="🙂"
    /><br />
Oder ich bin einfach zu müde und zu viel gelernt heute, vielleicht bring ich ein paar Dinge grad völlig durcheinander <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>Grüssli</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1632152</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1632152</guid><dc:creator><![CDATA[Dravere]]></dc:creator><pubDate>Wed, 17 Dec 2008 22:00:06 GMT</pubDate></item><item><title><![CDATA[Reply to Templates und deren Grenzen on Wed, 17 Dec 2008 22:59:28 GMT]]></title><description><![CDATA[<p>bisher hat der msvc eigtl immer warnungen gebracht, wenn er was gemacht hat, was noch nicht im standard zu finden ist, deshalb war ich davon ausgegangen, dass partielle Spezialisierung durchaus im Standard ist - aber kA, das war ja jz au net mehr das Problem ^^</p>
<p>Ich habe jz folgenden Code:<br />
Aber anscheind wird im nicht-bad_alloc-Fall nicht der komplette Speicher freigegeben (ein vergleichsmäßig kleiner Teil wird &quot;vergessen&quot;, glaube ich) und ohne den cast auf char* hab ichs gar nicht hinbekommen - womit die Probleme mit Padding bleiben - die ich aber zumindest mit den aktuell verwendeten Datentypen umgehe (Pointer bzw double sollten ja von der größe her beide gut geeignet sein)</p>
<p>Helfer für CTor (placement new) und DTor (expliziter DTor-Aufruf + delete)</p>
<pre><code class="language-cpp">template &lt;typename T&gt;
void destruct(T * &amp;array_values, size_t count) throw()
{
	if(!array_values)
		return;

	for(SizeType i = SizeType(); i != count; ++i)
	{
		T *tmp = array_values + i;
		if (tmp)
			tmp-&gt;~T();
	}

	delete [] reinterpret_cast &lt;char*&gt; (array_values);
	array_values = nullptr;
}

template &lt;typename T, SizeType, typename TCtorArg&gt;
void init(T * &amp;array_values, size_t count, const TCtorArg &amp;ctor_argument = TCtorArg())
{
	try
	{
		array_values = reinterpret_cast &lt;T*&gt; ( new char[sizeof(T) * count] );
	}
	catch (...)
	{
		array_values = nullptr;
		throw;
	}

	for(SizeType i = SizeType(); i != count; ++i)
	{
		try
		{
			new (array_values + i) T(ctor_argument);
		}
		catch (...)
		{
			destruct(array_values, i);
			throw;
		}
	}
}
</code></pre>
<p>die ich wie folg verwendet habe:</p>
<pre><code class="language-cpp">Line(ValueType fill_with = ValueType())
{
	try
	{
		alloc::placement_new::init(values, row_count, fill_with);
	}
	catch (...)
	{
		alloc::placement_new::destruct(values, row_count);
		throw;
	}
}

~Line() throw()
{
	alloc::placement_new::destruct(values, row_count);
}

TMatrix(ValueType fill_with = ValueType())
{
	try
	{
		alloc::placement_new::init(lines, line_count, fill_with);
	}
	catch (...)
	{
		alloc::placement_new::destruct(lines, line_count);
		throw;
	}
}

~TMatrix() throw()
{
	alloc::placement_new::destruct(lines, line_count);
}
</code></pre>
<p>Ich wäre über eine Reaktion sehr erfreut ^^</p>
<p>bb</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1632175</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1632175</guid><dc:creator><![CDATA[unskilled]]></dc:creator><pubDate>Wed, 17 Dec 2008 22:59:28 GMT</pubDate></item><item><title><![CDATA[Reply to Templates und deren Grenzen on Thu, 18 Dec 2008 08:52:15 GMT]]></title><description><![CDATA[<p>die try catch sind meines Wissens nicht nötig. Was ich dir oben versucht hab zu sagen ist folgendes:</p>
<pre><code class="language-cpp">class B
{
  A* aptr;
  C  c;

public:
  B() : aptr(new A()), c() 
  {}
};
</code></pre>
<p>Wenn jetzt z.B. der Konstruktor von c eine Exception auslöst, dann geschieht folgendes:<br />
- alle bis dahin initialisierten Member von B werden zerstört. Da aptr ein POD ist und keinen Dtor hat wirds einfach gelöscht. Speicherleck geschaffen<br />
- Da der Ctor von B nicht vollständig ausgeführt worden ist, hat das B-Objekt nie exisitiert, also wird auch kein Dtor für B aufgerufen. Speicherleck lebt weiter.<br />
- da das B-Objekt nie existiert hat, kann auch von außen niemand den für aptr allokierten Speicher freigeben. Das Speicherleck bleibt also und ist nicht mehr zu retten.</p>
<p>Meine Aussage war also lediglich, dass die Aufrufe von new() in der Init-Liste eines Ctors für einfache Pointer nicht exceptionsicher sind.<br />
Folgende Möglichkeiten gibts:</p>
<pre><code class="language-cpp">class B1
{
  A* aptr;
  C  c;

public:
  B1() : aptr(0), c() 
  {
    try {
     aptr = new a(); 
    }
    catch(...)
    { /* delete alle pointer */ }
  }
};

class B2
{
  shared_ptr&lt;A&gt; aptr;
  C  c;

public:
  B2() : aptr(new A()), c() 
  {}
};
</code></pre>
<p>Bei Variante 1 kann man das try/catch weglassen, wenns nur einen Pointer in der Klasse gibt der so initialisiert wird. Bei einem fehlschlagenden new wid der allokierte Speicher immer freigegeben. Ab zwei Pointern muss aber try/catch eingebaut werden: wenn das zweite new eine exception wirft muss der erste seinen Speicher freigeben.<br />
Variante 2 geht deshalb, weil der smart-pointer den allokierten speicher wieder freigibt, wenn im Laufe der Konstruktion von B2 eine exception fliegt.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1632266</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1632266</guid><dc:creator><![CDATA[pumuckl]]></dc:creator><pubDate>Thu, 18 Dec 2008 08:52:15 GMT</pubDate></item></channel></rss>