<?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[Template-Spezialisierung (Speicherverbrauch ermitteln)]]></title><description><![CDATA[<p>Ich möchte eine Funktion schreiben, die mir den ungefähren Speicherverbrauch eines Objekts zurückgibt. Für triviale Typen t wird einfach sizeof(t) zurückgegeben:</p>
<pre><code>template &lt;class T&gt;
typename std::enable_if&lt;std::is_trivial&lt;T&gt;::value, size_t&gt;::type memory(const T&amp; obj) {
    return sizeof(obj);
}
</code></pre>
<p>Für std::deque könnte die Implementierung so aussehen:</p>
<pre><code>template &lt;class U&gt;
size_t memory(const std::deque&lt;U&gt;&amp; obj) {
    size_t sum = sizeof(obj);
    for (const U&amp; u: obj) {
        sum += memory(u);
    }
    return sum;
}
</code></pre>
<p>Der berechnete Wert ist nicht exakt, aber für meine Zwecke reicht das aus. Mein Problem ist nun, dass der Compiler die Definition der memory-Funktion manchmal nicht &quot;findet&quot;:</p>
<pre><code>template &lt;DimType DIMENSION, class T&gt;
class QuadLeafManager {
public:
    struct FileInterval {
        //...
    }
}

template &lt;DimType DIMENSION, class T&gt;
size_t memory(const typename QuadLeafManager&lt;DIMENSION, T&gt;::FileInterval&amp; fint) {
    return sizeof(fint);
}
</code></pre>
<p>In der Überladung von memory(QuadLeafManager) wird memory(std::vector&lt;FileInterval&gt;) aufgerufen:</p>
<pre><code>error: no matching function for call to 'memory(const External::QuadLeafManager&lt;4u, float&gt;::FileInterval&amp;)'
         sum += memory(u); // &lt;- dies ist der Aufruf in memory(std::vector&lt;T&gt;)
</code></pre>
<p>Möglicherweise ist mein Ansatz schon verkehrt. Am liebsten hätte ich die Funktion standardmäßig als sizeof(...) definiert und sie bei Bedarf (std::vector, usw.) überladen. Wenn ich das richtig verstanden hab, kann man Funktionstemplates nicht partial spezialieren.</p>
<p>Wäre es besser memory() als Klasse zu deklarieren, in etwa so:</p>
<pre><code>template &lt;class T&gt;
struct Memory {
    static size_t get(const T&amp; t) {
        return sizeof(t);
    }
};

template &lt;class U&gt;
struct Memory&lt;std::vector&lt;U&gt;&gt; {
    static size_t get(const std::vector&lt;U&gt;&amp; v) {
        size_t sum = sizeof(v);
        for (const U&amp; u: v) {
            sum += Memory&lt;U&gt;::get(u);
        }
        return sum;
    }
};
</code></pre>
<p>Der Aufruf kann dann aber etwas nervig sein, da man immer den Type angeben muss:</p>
<pre><code>Memory&lt;std::vector&lt;int&gt;&gt;::get(xyz);
</code></pre>
<p>Wie implementiert man mein Vorhaben am Besten?</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/331267/template-spezialisierung-speicherverbrauch-ermitteln</link><generator>RSS for Node</generator><lastBuildDate>Fri, 01 May 2026 19:16:19 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/331267.rss" rel="self" type="application/rss+xml"/><pubDate>Thu, 19 Feb 2015 12:43:03 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Template-Spezialisierung (Speicherverbrauch ermitteln) on Thu, 19 Feb 2015 12:43:03 GMT]]></title><description><![CDATA[<p>Ich möchte eine Funktion schreiben, die mir den ungefähren Speicherverbrauch eines Objekts zurückgibt. Für triviale Typen t wird einfach sizeof(t) zurückgegeben:</p>
<pre><code>template &lt;class T&gt;
typename std::enable_if&lt;std::is_trivial&lt;T&gt;::value, size_t&gt;::type memory(const T&amp; obj) {
    return sizeof(obj);
}
</code></pre>
<p>Für std::deque könnte die Implementierung so aussehen:</p>
<pre><code>template &lt;class U&gt;
size_t memory(const std::deque&lt;U&gt;&amp; obj) {
    size_t sum = sizeof(obj);
    for (const U&amp; u: obj) {
        sum += memory(u);
    }
    return sum;
}
</code></pre>
<p>Der berechnete Wert ist nicht exakt, aber für meine Zwecke reicht das aus. Mein Problem ist nun, dass der Compiler die Definition der memory-Funktion manchmal nicht &quot;findet&quot;:</p>
<pre><code>template &lt;DimType DIMENSION, class T&gt;
class QuadLeafManager {
public:
    struct FileInterval {
        //...
    }
}

template &lt;DimType DIMENSION, class T&gt;
size_t memory(const typename QuadLeafManager&lt;DIMENSION, T&gt;::FileInterval&amp; fint) {
    return sizeof(fint);
}
</code></pre>
<p>In der Überladung von memory(QuadLeafManager) wird memory(std::vector&lt;FileInterval&gt;) aufgerufen:</p>
<pre><code>error: no matching function for call to 'memory(const External::QuadLeafManager&lt;4u, float&gt;::FileInterval&amp;)'
         sum += memory(u); // &lt;- dies ist der Aufruf in memory(std::vector&lt;T&gt;)
</code></pre>
<p>Möglicherweise ist mein Ansatz schon verkehrt. Am liebsten hätte ich die Funktion standardmäßig als sizeof(...) definiert und sie bei Bedarf (std::vector, usw.) überladen. Wenn ich das richtig verstanden hab, kann man Funktionstemplates nicht partial spezialieren.</p>
<p>Wäre es besser memory() als Klasse zu deklarieren, in etwa so:</p>
<pre><code>template &lt;class T&gt;
struct Memory {
    static size_t get(const T&amp; t) {
        return sizeof(t);
    }
};

template &lt;class U&gt;
struct Memory&lt;std::vector&lt;U&gt;&gt; {
    static size_t get(const std::vector&lt;U&gt;&amp; v) {
        size_t sum = sizeof(v);
        for (const U&amp; u: v) {
            sum += Memory&lt;U&gt;::get(u);
        }
        return sum;
    }
};
</code></pre>
<p>Der Aufruf kann dann aber etwas nervig sein, da man immer den Type angeben muss:</p>
<pre><code>Memory&lt;std::vector&lt;int&gt;&gt;::get(xyz);
</code></pre>
<p>Wie implementiert man mein Vorhaben am Besten?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2443404</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2443404</guid><dc:creator><![CDATA[Ramanujan]]></dc:creator><pubDate>Thu, 19 Feb 2015 12:43:03 GMT</pubDate></item><item><title><![CDATA[Reply to Template-Spezialisierung (Speicherverbrauch ermitteln) on Thu, 19 Feb 2015 13:06:47 GMT]]></title><description><![CDATA[<p>Du musst schon angeben, was in welchem Namespace liegt. Und was hat <code>deque</code> mit dem Problem zu tun, wenn es um <code>vector</code> geht?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2443409</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2443409</guid><dc:creator><![CDATA[TyRoXx]]></dc:creator><pubDate>Thu, 19 Feb 2015 13:06:47 GMT</pubDate></item><item><title><![CDATA[Reply to Template-Spezialisierung (Speicherverbrauch ermitteln) on Thu, 19 Feb 2015 14:31:08 GMT]]></title><description><![CDATA[<p>Ramanujan schrieb:</p>
<blockquote>
<pre><code>template &lt;class T&gt;
typename std::enable_if&lt;std::is_trivial&lt;T&gt;::value, size_t&gt;::type memory(const T&amp; obj) {
    return sizeof(obj);
}
</code></pre>
</blockquote>
<p>Ich nehme mal an, dieses Template befindet sich im globalen Namensraum</p>
<p>Ramanujan schrieb:</p>
<blockquote>
<p>Mein Problem ist nun, dass der Compiler die Definition der memory-Funktion manchmal nicht &quot;findet&quot;:</p>
<pre><code>template &lt;DimType DIMENSION, class T&gt;
class QuadLeafManager {
public:
    struct FileInterval {
        //...
    }
}

template &lt;DimType DIMENSION, class T&gt;
size_t memory(const typename QuadLeafManager&lt;DIMENSION, T&gt;::FileInterval&amp; fint) {
    return sizeof(fint);
}
</code></pre>
<p>In der Überladung von memory(QuadLeafManager) wird memory(std::vector&lt;FileInterval&gt;) aufgerufen:</p>
<pre><code>error: no matching function for call to 'memory(const External::QuadLeafManager&lt;4u, float&gt;::FileInterval&amp;)'
         sum += memory(u); // &lt;- dies ist der Aufruf in memory(std::vector&lt;T&gt;)
</code></pre>
</blockquote>
<p>Die Variante für triviale Typen kann im Allgemeinen nicht per ADL gefunden werden. In einem Aufruf der Form</p>
<pre><code class="language-cpp">sum += memory(u);
</code></pre>
<p>muss folglich das normale unqualifizierte Lookup erfolgreich sein. Befinden wir uns aber im Namensraum External, und befindet sich in External eine weitere Deklaration einer memory-Funktion, verdeckt diese nat. das Template im globalen Namensraum.<br />
Die übliche Verfahrensweise ist hier, die Deklarationen, die nicht per ADL gefunden werden, per using-Deklaration in der Funktion bekannt zu machen.<br />
Also</p>
<pre><code class="language-cpp">template &lt;class U&gt;
size_t memory(const std::deque&lt;U&gt;&amp; obj) {
    using ::memory; //
    size_t sum = sizeof(obj);
    for (const U&amp; u: obj) {
        sum += memory(u);
    }
    return sum;
}
</code></pre>
<p>Das ist die gleiche Herangehensweise die auch bei der Verwendung von swap genutzt werden sollte.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2443422</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2443422</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Thu, 19 Feb 2015 14:31:08 GMT</pubDate></item><item><title><![CDATA[Reply to Template-Spezialisierung (Speicherverbrauch ermitteln) on Thu, 19 Feb 2015 15:59:57 GMT]]></title><description><![CDATA[<p>Hm, irgendwie bin ich gerade verwirrt. Wenn ich versuche, den Fehler durch ein Minimalbeispiel zu reproduzieren, kompiliert alles fehlerfrei.</p>
<p>Mit dem &quot;using ::memory&quot; hilft schon mal nicht.</p>
<p>Noch eine andere Frage:<br />
Was kann ich machen, wenn ich möchte, dass memory(T&amp; t) standardmäßig sizeof(t) zurückgibt?</p>
<p>Edit:<br />
ok, jetzt geht alles, auch wenn ich noch nicht genau vestehe warum.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2443442</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2443442</guid><dc:creator><![CDATA[Ramanujan]]></dc:creator><pubDate>Thu, 19 Feb 2015 15:59:57 GMT</pubDate></item></channel></rss>