<?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[Klassen Template Spezialisierung fuer Pointer]]></title><description><![CDATA[<p>Hallo,</p>
<p>derzeit werden im Projekt geometrische Punkte und Mesh-Knoten in Vektoren auf verschiedene Art und Weisen verwaltet:</p>
<pre><code class="language-cpp">// case A: pointer to GeoLib::Point
std::vector&lt;GeoLib::Point*&gt; p_points;
// case B: pure GeoLib::Point
std::vector&lt;GeoLib::Point&gt; points;
// case A: pointer to MeshLib::Node
std::vector&lt;MeshLib::Node*&gt; p_nodes;
// case B: pure MeshLib::Node
std::vector&lt;MeshLib::Node&gt; nodes;
</code></pre>
<p>Um die Suche nach Punkten bzw. Mesh-Knoten effizient zu gestalten, soll das Klassen Template Grid verwendet werden. Das Grid verwaltet die Punkte/ Mesh-Knoten in einem Array von Vektoren:</p>
<pre><code class="language-cpp">std::vector&lt;POINT*&gt;* _grid_cell_to_node_map;
</code></pre>
<p>In den Vektoren des Arrays werden Pointer auf Punkte/Mesh-Knoten gespeichert die zu einer entsprechenden Hexaeder-Zelle gehoeren.</p>
<pre><code class="language-cpp">template &lt;typename POINT&gt; class Grid 
{
    public:
        Grid(std::vector&lt;POINT&gt; const&amp; pnts, size_t max_num_per_grid_cell = 512);
        // some template type independend methods

    private:
        std::vector&lt;POINT*&gt;* _grid_cell_to_node_map;
};
</code></pre>
<p>Fuer die Faelle (s.o. case A), das dem Konstruktor ein vector&lt;PointerType&gt; uebergeben wird habe ich eine Spezialisierung geschrieben.</p>
<pre><code class="language-cpp">template &lt;typename POINT&gt; class Grid&lt;POINT*&gt;
{
    public:
        Grid(std::vector&lt;POINT*&gt; const&amp; pnts, size_t max_num_per_grid_cell = 512);
        // copy of template type independend methods

    private:
        std::vector&lt;POINT*&gt;* _grid_cell_to_node_map;
};
</code></pre>
<p>Nun enthaelt mein Klassen Template aber recht viel Quelltext der eigentlich nicht davon abhaengig ist ob der zur Konstruktion des Objekts uebergebene Vektor Pointer-Typen oder Wert-Typen enthaelt. Eigentlich soll lediglich der Objekt-Konstruktions-Prozess modifiziert werden. Die restliche Funktionalitaet der Klasse ist unabhaengig ob Pointer- oder Wert-Typ uebergeben werden. Gibt es da eine elegante Loesung, ohne die meiste Funktionalitatet zu kopieren?</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/307527/klassen-template-spezialisierung-fuer-pointer</link><generator>RSS for Node</generator><lastBuildDate>Thu, 06 Aug 2026 19:13:28 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/307527.rss" rel="self" type="application/rss+xml"/><pubDate>Wed, 29 Aug 2012 07:51:54 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Klassen Template Spezialisierung fuer Pointer on Wed, 29 Aug 2012 07:51:54 GMT]]></title><description><![CDATA[<p>Hallo,</p>
<p>derzeit werden im Projekt geometrische Punkte und Mesh-Knoten in Vektoren auf verschiedene Art und Weisen verwaltet:</p>
<pre><code class="language-cpp">// case A: pointer to GeoLib::Point
std::vector&lt;GeoLib::Point*&gt; p_points;
// case B: pure GeoLib::Point
std::vector&lt;GeoLib::Point&gt; points;
// case A: pointer to MeshLib::Node
std::vector&lt;MeshLib::Node*&gt; p_nodes;
// case B: pure MeshLib::Node
std::vector&lt;MeshLib::Node&gt; nodes;
</code></pre>
<p>Um die Suche nach Punkten bzw. Mesh-Knoten effizient zu gestalten, soll das Klassen Template Grid verwendet werden. Das Grid verwaltet die Punkte/ Mesh-Knoten in einem Array von Vektoren:</p>
<pre><code class="language-cpp">std::vector&lt;POINT*&gt;* _grid_cell_to_node_map;
</code></pre>
<p>In den Vektoren des Arrays werden Pointer auf Punkte/Mesh-Knoten gespeichert die zu einer entsprechenden Hexaeder-Zelle gehoeren.</p>
<pre><code class="language-cpp">template &lt;typename POINT&gt; class Grid 
{
    public:
        Grid(std::vector&lt;POINT&gt; const&amp; pnts, size_t max_num_per_grid_cell = 512);
        // some template type independend methods

    private:
        std::vector&lt;POINT*&gt;* _grid_cell_to_node_map;
};
</code></pre>
<p>Fuer die Faelle (s.o. case A), das dem Konstruktor ein vector&lt;PointerType&gt; uebergeben wird habe ich eine Spezialisierung geschrieben.</p>
<pre><code class="language-cpp">template &lt;typename POINT&gt; class Grid&lt;POINT*&gt;
{
    public:
        Grid(std::vector&lt;POINT*&gt; const&amp; pnts, size_t max_num_per_grid_cell = 512);
        // copy of template type independend methods

    private:
        std::vector&lt;POINT*&gt;* _grid_cell_to_node_map;
};
</code></pre>
<p>Nun enthaelt mein Klassen Template aber recht viel Quelltext der eigentlich nicht davon abhaengig ist ob der zur Konstruktion des Objekts uebergebene Vektor Pointer-Typen oder Wert-Typen enthaelt. Eigentlich soll lediglich der Objekt-Konstruktions-Prozess modifiziert werden. Die restliche Funktionalitaet der Klasse ist unabhaengig ob Pointer- oder Wert-Typ uebergeben werden. Gibt es da eine elegante Loesung, ohne die meiste Funktionalitatet zu kopieren?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2246520</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2246520</guid><dc:creator><![CDATA[123_tom_dabei]]></dc:creator><pubDate>Wed, 29 Aug 2012 07:51:54 GMT</pubDate></item><item><title><![CDATA[Reply to Klassen Template Spezialisierung fuer Pointer on Wed, 29 Aug 2012 07:58:06 GMT]]></title><description><![CDATA[<p>Ist nur der Konstruktorrumpf verschieden? Dann würde ich dort eine Funktion aufrufen, die für <code>T</code> und <code>T*</code> überladen ist.</p>
<p>Warum speicherst du eigentlich den <code>std::vector</code> selbst als Zeiger? Willst du ihn nicht automatisch verwalten lassen, d.h.</p>
<pre><code class="language-cpp">std::vector&lt;POINT*&gt; _grid_cell_to_node_map;
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2246521</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2246521</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Wed, 29 Aug 2012 07:58:06 GMT</pubDate></item><item><title><![CDATA[Reply to Klassen Template Spezialisierung fuer Pointer on Wed, 29 Aug 2012 08:19:42 GMT]]></title><description><![CDATA[<p>Hallo Nexus,</p>
<p>danke fuer die schnelle Antwort. Im Prinzip ist nur der Konstruktor verschieden.<br />
Ich habe auch schon Folgendes versucht:</p>
<pre><code class="language-cpp">template &lt;typename POINT&gt; class Grid
{
    public:
        // constructor 1
        Grid(std::vector&lt;POINT&gt; const&amp; pnts, size_t max_num_per_grid_cell = 512);
        // constructor 2
        Grid(std::vector&lt;POINT*&gt; const&amp; pnts, size_t max_num_per_grid_cell = 512);
        // some template type independend methods

    private:
        std::vector&lt;POINT*&gt;* _grid_cell_to_node_map;
};
</code></pre>
<p>Schreibe ich</p>
<pre><code class="language-cpp">std::vector&lt;Node*&gt; nodes;
// fill the vector
GeoLib::Grid&lt;Node*&gt;* grid(new GeoLib::Grid&lt;Node*&gt;(nodes, 64));
</code></pre>
<p>wird nicht Konstruktor 2 ausgewaehlt, wie von mir erwuenscht, sondern Konstruktor 1 was (logischerweise) zu Kompilierproblemen fuehrt.</p>
<p>Zu deiner zweiten Frage warum ich den vector als Zeiger abspeichere. Dies ist eine Array von Vektoren. Jeder Vektor in diesem Array korrespondiert zu einer Grid-Zelle. Die Anzahl der Grid-Zellen lege ich einmal im Konstruktor fest und die Anzahl aendert sich auch nicht mehr. Deswegen habe ich ein Array genommen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2246530</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2246530</guid><dc:creator><![CDATA[123_tom_dabei]]></dc:creator><pubDate>Wed, 29 Aug 2012 08:19:42 GMT</pubDate></item><item><title><![CDATA[Reply to Klassen Template Spezialisierung fuer Pointer on Wed, 29 Aug 2012 08:39:48 GMT]]></title><description><![CDATA[<p>da du doch aber vectoren kennst, kannst du dort auch einen benutzen?<br />
Bei deinem Template übergibst du Node* als typename. Damit hast du anschließend</p>
<pre><code class="language-cpp">Grid(std::vector&lt;Node*&gt; const&amp; pnts, size_t max_num_per_grid_cell = 512);
Grid(std::vector&lt;Node**&gt; const&amp; pnts, size_t max_num_per_grid_cell = 512);
</code></pre>
<p>und das ist ja nicht das, was du möchtest.</p>
<p>greetz KN4CK3R</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2246538</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2246538</guid><dc:creator><![CDATA[KN4CK3R]]></dc:creator><pubDate>Wed, 29 Aug 2012 08:39:48 GMT</pubDate></item><item><title><![CDATA[Reply to Klassen Template Spezialisierung fuer Pointer on Wed, 29 Aug 2012 08:45:20 GMT]]></title><description><![CDATA[<p>123_tom_dabei schrieb:</p>
<blockquote>
<p>Ich habe auch schon Folgendes versucht</p>
</blockquote>
<p>Versuch mal den erwähnten Ansatz mit Überladung.</p>
<p>123_tom_dabei schrieb:</p>
<blockquote>
<p>Zu deiner zweiten Frage warum ich den vector als Zeiger abspeichere. Dies ist eine Array von Vektoren. Jeder Vektor in diesem Array korrespondiert zu einer Grid-Zelle. Die Anzahl der Grid-Zellen lege ich einmal im Konstruktor fest und die Anzahl aendert sich auch nicht mehr. Deswegen habe ich ein Array genommen.</p>
</blockquote>
<p>Dann nimm bitte auch ein Array, sodass du Speicher nicht selbst verwalten musst. Falls du die Grösse zur Kompilierzeit weisst:</p>
<pre><code class="language-cpp">std::array&lt; std::vector&lt;POINT*&gt;, groesse &gt; _grid_cell_to_node_map;
</code></pre>
<p>Falls die Grösse dynamisch ist, verschachtle zwei Vectors:</p>
<pre><code class="language-cpp">std::vector&lt; std::vector&lt;POINT*&gt; &gt; _grid_cell_to_node_map;
</code></pre>
<p>Auch beim Element <code>POINT*</code> gilt: Wenn die Zeiger nur Verweise sind, ist alles ok. Wenn du aber <code>new</code> und <code>delete</code> anwendest, machst du dir das Leben unnötig schwer. Manuelle Speicherverwaltung sollte wann immer möglich vermieden werden.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2246540</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2246540</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Wed, 29 Aug 2012 08:45:20 GMT</pubDate></item><item><title><![CDATA[Reply to Klassen Template Spezialisierung fuer Pointer on Wed, 29 Aug 2012 08:45:05 GMT]]></title><description><![CDATA[<p>SFINAE könnte weiterhelfen</p>
<pre><code class="language-cpp">#include &lt;type_traits&gt;

template &lt;typename POINT&gt; class Grid
{
    public:
        // constructor 1
        template &lt;typename T, typename = typename std::enable_if&lt;std::is_same&lt;T, POINT&gt;::value &amp;&amp; !std::is_pointer&lt;T&gt;::value&gt;::type&gt;
        Grid(std::vector&lt;T&gt; const&amp; pnts, size_t max_num_per_grid_cell = 512);
        // constructor 2
        template &lt;typename T, typename = typename std::enable_if&lt;std::is_same&lt;T, POINT&gt;::value &amp;&amp; std::is_pointer&lt;T&gt;::value&gt;::type&gt;
        Grid(std::vector&lt;T&gt; const&amp; pnts, size_t max_num_per_grid_cell = 512);
        // some template type independend methods

    private:
        std::vector&lt;typename std::add_pointer&lt;typename std::remove_pointer&lt;POINT&gt;::type&gt;::type&gt;* _grid_cell_to_node_map;
};
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2246542</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2246542</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Wed, 29 Aug 2012 08:45:05 GMT</pubDate></item><item><title><![CDATA[Reply to Klassen Template Spezialisierung fuer Pointer on Wed, 29 Aug 2012 08:55:37 GMT]]></title><description><![CDATA[<p>@ KN4CK3R<br />
Okay, die Frage ob Array von Vektoren oder Vektor von Vektoren ist sicher ein bedenkenswerter Aspekt.</p>
<p>Aber mein Hauptproblem ist ja ein anderes. Ich moechte das Klassen Template sowohl fuer</p>
<pre><code class="language-cpp">vector&lt;PointerToPointTyp&gt;
</code></pre>
<p>als auch fuer</p>
<pre><code class="language-cpp">vector&lt;PointTyp&gt;
</code></pre>
<p>benutzen ohne die nicht Pointer- bzw. Wert-Typ abhaengige Funktionalitaet der Klasse kopieren zu muessen. Im Prinzip brauche ich so eine Art</p>
<pre><code class="language-cpp">if (PointerTyp)
    use constructor 2
else
    use constructor 1
</code></pre>
<p>oder eine Moeglichkeit bestimmte Methoden aus dem &quot;unspezialisierten&quot; Klassen Template zu uebernehmen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2246548</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2246548</guid><dc:creator><![CDATA[123_tom_dabei]]></dc:creator><pubDate>Wed, 29 Aug 2012 08:55:37 GMT</pubDate></item><item><title><![CDATA[Reply to Klassen Template Spezialisierung fuer Pointer on Wed, 29 Aug 2012 09:32:54 GMT]]></title><description><![CDATA[<p>Hallo camper,</p>
<p>camper schrieb:</p>
<blockquote>
<p>SFINAE könnte weiterhelfen</p>
</blockquote>
<p>Das klingt irgendwie nach einer Loesung. Leider bekomme ich einen Compile-Fehler</p>
<blockquote>
<p>error: ‘template&lt;class POINT&gt; template&lt;class T, class&gt; GeoLib::Grid::Grid(const std::vector&lt;T&gt;&amp;, size_t)’ cannot be overloaded</p>
</blockquote>
<p>fuer Konstruktor 2.</p>
<p>camper schrieb:</p>
<blockquote>
<pre><code class="language-cpp">// constructor 2
        template &lt;typename T, typename = typename std::enable_if&lt;std::is_same&lt;T, POINT&gt;::value &amp;&amp; std::is_pointer&lt;T&gt;::value&gt;::type&gt;
        Grid(std::vector&lt;T&gt; const&amp; pnts, size_t max_num_per_grid_cell = 512);
</code></pre>
</blockquote>
<p>Ich wuerde die Konstrukte auch gerne verstehen. Gibt es da Links oder Artikel in denen die Konstrukte erklaert werden? Wozu wird zum Beispiel std::is_same&lt;T, POINT&gt; verwendet? Warum reicht es nicht aus std::is_pointer&lt;...&gt; zu verwenden. Das ist mir alles nicht richtig klar.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2246570</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2246570</guid><dc:creator><![CDATA[123_tom_dabei]]></dc:creator><pubDate>Wed, 29 Aug 2012 09:32:54 GMT</pubDate></item><item><title><![CDATA[Reply to Klassen Template Spezialisierung fuer Pointer on Wed, 29 Aug 2012 10:01:02 GMT]]></title><description><![CDATA[<p>123_tom_dabei schrieb:</p>
<blockquote>
<p>Hallo camper,</p>
<p>camper schrieb:</p>
<blockquote>
<p>SFINAE könnte weiterhelfen</p>
</blockquote>
<p>Das klingt irgendwie nach einer Loesung. Leider bekomme ich einen Compile-Fehler</p>
<blockquote>
<p>error: ‘template&lt;class POINT&gt; template&lt;class T, class&gt; GeoLib::Grid::Grid(const std::vector&lt;T&gt;&amp;, size_t)’ cannot be overloaded</p>
</blockquote>
</blockquote>
<p>Ja, der Fehler passiert mir fast immer, wenn ich so etwas schreibe...<br />
Damit zwei Funktionstemplates überladen werden können, müssen sie sich in ihren Funktionsargumenten oder in der Templateargumentliste unterscheiden, das ist hier aber nicht der Fall (Default-Templateargumente zählen nicht). Das kann man durch Hinzufügen eines weiteren Dummy-Parameters zu einer Überladung lösen, oder indem der kein Typ-Parameter verwendet wird</p>
<pre><code class="language-cpp">// constructor 1
        template &lt;typename T, typename std::enable_if&lt;std::is_same&lt;T, POINT&gt;::value &amp;&amp; !std::is_pointer&lt;T&gt;::value, int&gt;::type = 0&gt;
        Grid(std::vector&lt;T&gt; const&amp; pnts, size_t max_num_per_grid_cell = 512);
        // constructor 2
        template &lt;typename T, bool dummy = true, typename std::enable_if&lt;std::is_same&lt;T, POINT&gt;::value &amp;&amp; std::is_pointer&lt;T&gt;::value, int&gt;::type = 0&gt;
        Grid(std::vector&lt;T&gt; const&amp; pnts, size_t max_num_per_grid_cell = 512);
</code></pre>
<p>123_tom_dabei schrieb:</p>
<blockquote>
<p>Ich wuerde die Konstrukte auch gerne verstehen. Gibt es da Links oder Artikel in denen die Konstrukte erklaert werden?</p>
</blockquote>
<p>Artikel habe ich gerade nicht zur Hand, vielleicht will jemand es erklären? Sonst schreib ich später noch was dazu.</p>
<p>123_tom_dabei schrieb:</p>
<blockquote>
<p>Wozu wird zum Beispiel std::is_same&lt;T, POINT&gt; verwendet? Warum reicht es nicht aus std::is_pointer&lt;...&gt; zu verwenden.</p>
</blockquote>
<p>Du willst ja nur mit Vektoren arbeiten, die ein POINT enthalten, nicht irgendetwas anderes wie vector&lt;list&lt;complex&lt;float&gt;&gt;&gt; oder vector&lt;void(*)()&gt; oder so.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2246590</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2246590</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Wed, 29 Aug 2012 10:01:02 GMT</pubDate></item><item><title><![CDATA[Reply to Klassen Template Spezialisierung fuer Pointer on Wed, 29 Aug 2012 16:11:29 GMT]]></title><description><![CDATA[<p>Niemand der etwas zu SFINAE schreiben will? Wikipedia enhält einen brauchbaren Eintrag, die Erklärung in <a href="http://www.boost.org/doc/libs/1_51_0/libs/utility/enable_if.html" rel="nofollow">boost</a> ist auch ganz brauchbar, geht allerdings nicht auf erst in C++11 mögliche syntaktische Konstrukte ein.</p>
<p>In Hinblick auf die Ausgangsfrage lässt sich wahrscheinlich eine elegantere Lösung finden. Soweit ich das sehe, soll grid_cell_to_node_map am Ende entweder Verweise auf die Elemente des initialisierenden Containers (wenn es ein vector&lt;T&gt; war) oder auf die durch den initialisierenden Vector referenzierten Objekte (im Fall vector&lt;T*&gt;) enthalten. Dann lässt sich das Ganze stark vereinfachen, und eigentlich kommt es gar nicht darauf an, of die Elemente sich ursprünglich in einem vector befinden, ein Iteratorpaar genügt.</p>
<pre><code class="language-cpp">template &lt;typename POINT&gt; class Grid
{
    private:
        static POINT* copy_or_address(POINT&amp; p) { return &amp;p; }
        static POINT* copy_or_address(POINT* p) { return p; }
    public:
        template &lt;typename InputIterator&gt;
        Grid(InputIterator first, InputIerator last, size_t max_num_per_grid_cell = 512); // überall einfach copy_or_address(*it) verwenden

    private:
        std::vector&lt;POINT*&gt; _grid_cell_to_node_map;
};
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2246762</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2246762</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Wed, 29 Aug 2012 16:11:29 GMT</pubDate></item></channel></rss>