<?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[Linker: Templates + .cpp Datei = böse?]]></title><description><![CDATA[<p>Hallihallo!</p>
<p>Ich arbeite gerade mit Sockets, um genau zu sein mit der C-API. (boost::asio kommt nicht in Frage.) Ich habe ein Template, das mir die select() Funktion kapselt, die Deklaration sieht so aus:</p>
<pre><code class="language-cpp">template &lt;typename InputIterator&gt;
std::vector&lt;typename InputIterator::value_type*&gt; select(InputIterator begin, InputIterator end, int timeout, int microtimeout);
</code></pre>
<p>Jedenfalls würde ich diese Template gerne in eine .cpp auslagern, da ich die C-Includes in meinen Headern vermeiden möchte. Gibts da irgendwas? Kann man das mit dem neuen 'extern' Schlüsselwort machen?</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/291039/linker-templates-cpp-datei-böse</link><generator>RSS for Node</generator><lastBuildDate>Mon, 17 Aug 2026 22:25:33 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/291039.rss" rel="self" type="application/rss+xml"/><pubDate>Tue, 09 Aug 2011 16:05:29 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Linker: Templates + .cpp Datei = böse? on Tue, 09 Aug 2011 16:05:29 GMT]]></title><description><![CDATA[<p>Hallihallo!</p>
<p>Ich arbeite gerade mit Sockets, um genau zu sein mit der C-API. (boost::asio kommt nicht in Frage.) Ich habe ein Template, das mir die select() Funktion kapselt, die Deklaration sieht so aus:</p>
<pre><code class="language-cpp">template &lt;typename InputIterator&gt;
std::vector&lt;typename InputIterator::value_type*&gt; select(InputIterator begin, InputIterator end, int timeout, int microtimeout);
</code></pre>
<p>Jedenfalls würde ich diese Template gerne in eine .cpp auslagern, da ich die C-Includes in meinen Headern vermeiden möchte. Gibts da irgendwas? Kann man das mit dem neuen 'extern' Schlüsselwort machen?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2104016</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2104016</guid><dc:creator><![CDATA[314159265358979]]></dc:creator><pubDate>Tue, 09 Aug 2011 16:05:29 GMT</pubDate></item><item><title><![CDATA[Reply to Linker: Templates + .cpp Datei = böse? on Tue, 09 Aug 2011 16:09:19 GMT]]></title><description><![CDATA[<p>314159265358979 schrieb:</p>
<blockquote>
<p>Jedenfalls würde ich diese Template gerne in eine .cpp auslagern, da ich die C-Includes in meinen Headern vermeiden möchte. Gibts da irgendwas? Kann man das mit dem neuen 'extern' Schlüsselwort machen?</p>
</blockquote>
<p>Nein, das kannst du nicht vollständig in eine eigene Übersetzungseinheit kapseln, weil der Compiler die komplette Definition des Templates kennen muß, um dort die parameterspzifischen Details ergänzen zu können.</p>
<p>PS: &quot;extern&quot; ist erstens nicht neu, zweitens von afaik nur einem Compiler wirklich umgesetzt worden und drittens auf bestem Weg, aus dem Sprachstandard gestrichen zu werden.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2104018</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2104018</guid><dc:creator><![CDATA[CStoll]]></dc:creator><pubDate>Tue, 09 Aug 2011 16:09:19 GMT</pubDate></item><item><title><![CDATA[Reply to Linker: Templates + .cpp Datei = böse? on Tue, 09 Aug 2011 16:10:46 GMT]]></title><description><![CDATA[<p>es gibt den trick die deklaration in die header datei zu schreiben und die implementierung in eine sogenannte *.impl datei<br />
und die impl wird am ende des headers inkludiert</p>
<p>bsp:</p>
<pre><code class="language-cpp">// foo.h
template&lt;class T&gt;
class Bar
{
   Bar(T const &amp; x);
   // ...
};

include &quot;foo.impl&quot;
</code></pre>
<pre><code class="language-cpp">// foo.impl
template&lt;class T&gt;
Bar::Bar(T const&amp; x)
{
    // ...
}

// ... Rest ...
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2104019</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2104019</guid><dc:creator><![CDATA[Skym0sh0]]></dc:creator><pubDate>Tue, 09 Aug 2011 16:10:46 GMT</pubDate></item><item><title><![CDATA[Reply to Linker: Templates + .cpp Datei = böse? on Tue, 09 Aug 2011 16:12:12 GMT]]></title><description><![CDATA[<p>Skym0sh0 schrieb:</p>
<blockquote>
<p>es gibt den trick die deklaration in die header datei zu schreiben und die implementierung in eine sogenannte *.impl datei<br />
und die impl wird am ende des headers inkludiert</p>
</blockquote>
<p>Dann hab ich doch erst wieder die C-Includes im Header.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2104020</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2104020</guid><dc:creator><![CDATA[314159265358979]]></dc:creator><pubDate>Tue, 09 Aug 2011 16:12:12 GMT</pubDate></item><item><title><![CDATA[Reply to Linker: Templates + .cpp Datei = böse? on Tue, 09 Aug 2011 16:15:27 GMT]]></title><description><![CDATA[<p>du schreibst also eine header datei wo du einige datien inkluden musst. aber du willst für spätere inkludierer eben diese inkludes verstecken?!</p>
<p>pimpl?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2104025</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2104025</guid><dc:creator><![CDATA[Skym0sh0]]></dc:creator><pubDate>Tue, 09 Aug 2011 16:15:27 GMT</pubDate></item><item><title><![CDATA[Reply to Linker: Templates + .cpp Datei = böse? on Tue, 09 Aug 2011 16:19:33 GMT]]></title><description><![CDATA[<p>Skym0sh0 schrieb:</p>
<blockquote>
<p>du schreibst also eine header datei wo du einige datien inkluden musst. aber du willst für spätere inkludierer eben diese inkludes verstecken?!</p>
</blockquote>
<p>Ich möchte einfach keine unnötigen C-Includes mitschleppen, die nur für die Implementierung relevant sind <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>Skym0sh0 schrieb:</p>
<blockquote>
<p>pimpl?</p>
</blockquote>
<p>pimpl kommt nicht in Frage, dafür ist eine Heap-Allokation erforderlich, und die ist zu teuer.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2104027</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2104027</guid><dc:creator><![CDATA[314159265358979]]></dc:creator><pubDate>Tue, 09 Aug 2011 16:19:33 GMT</pubDate></item><item><title><![CDATA[Reply to Linker: Templates + .cpp Datei = böse? on Tue, 09 Aug 2011 19:57:26 GMT]]></title><description><![CDATA[<p>CStoll schrieb:</p>
<blockquote>
<p>PS: &quot;extern&quot; ist erstens nicht neu, zweitens von afaik nur einem Compiler wirklich umgesetzt worden und drittens auf bestem Weg, aus dem Sprachstandard gestrichen zu werden.</p>
</blockquote>
<p>Das war &quot;export&quot;, was das Gegenteil von neu, nämlich deprecated ist.</p>
<p>Extern template im C++0x-Standard sorgt dafür, dass das als extern deklarierte Template in der entsprechenden ÜE nicht instantiiert wird.</p>
<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/26836">@Topic</a>: Wenn du die C-header nicht durch dein Projekt schleifen möchtest, musst du in den meisten ÜEs wohl auf die Definition der entsprechenden Funktionstemplates (das schließt Methoden von Klassentemplates mit ein) verzichten musst. Damit erübrigt sich das extern template für diese ÜEs, weil der Compiler dort sowieso nur die Deklarationen der entsprechenden Funktionen sieht. Allerdings musst du zu jeder Instantiierung der Funktionstemplates in irgendeiner ÜE auch die Definition mitliefern und dort instantiieren. Das wird ziemlich mühselig.</p>
<p>Wenns dir um Sauberkeit des globalen namespace usw. geht, würde ich folgendes vorschlagen:<br />
Erstelle einen eigenen Header, sagen wir &quot;cstdlib_forward.h&quot;, der passende Funktionen in einem eigenen namespace, sagen wir <code>namespace cstdlib_fwd</code> deklariert. Den bindest du in deinen Template-Header ein und rufst die Funktionen auf wie du sie brauchst. In cstdlib_forward.cpp werden die eigentlichen C-Header eingebunden und die Funktionen direkt an die entsprechenden C-Funktionen weitergeleitet. Ich lehne mich mal ganz weit aus dem Fenster und behaupte, dass ein aktueller Linker das erkennen und die extra-Funktion jeweils wegoptimieren sollte, so dass du einen sauberen globalen namespace und keinen Overhead haben solltest.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2104131</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2104131</guid><dc:creator><![CDATA[pumuckl]]></dc:creator><pubDate>Tue, 09 Aug 2011 19:57:26 GMT</pubDate></item><item><title><![CDATA[Reply to Linker: Templates + .cpp Datei = böse? on Tue, 09 Aug 2011 20:56:15 GMT]]></title><description><![CDATA[<p>Mach halt so:</p>
<pre><code class="language-cpp">namespace detail
{
int select_wrapper(...);
int socket_wrapper(...);
int send_wrapper(...);
int recv_wrapper(...);
// ...
}
// EDIT: std::iterator_traits&lt;InputIterator&gt;::value_type statt InputIterator::value_type
template &lt;typename InputIterator&gt; 
 std::vector&lt;typename std::iterator_traits&lt;InputIterator&gt;::value_type*&gt; select(InputIterator begin, InputIterator end, int timeout, int microtimeout)
{
    // implementieren mit Hilfe der &quot;detail&quot; Funktionen
}
</code></pre>
<p>Das ist so ziemlich *die* Standard-Variante wie man mit sowas umgeht. Also wenn man in den Header Files der eigenen LIB keine bösen fremden Header Files inkludieren will.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2104137</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2104137</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Tue, 09 Aug 2011 20:56:15 GMT</pubDate></item><item><title><![CDATA[Reply to Linker: Templates + .cpp Datei = böse? on Tue, 09 Aug 2011 20:36:02 GMT]]></title><description><![CDATA[<p>Kleine Anmerkung zum Code: statt <code>InputIterator::value_type</code> solltest du besser <code>std::iterator_traits&lt;InputIterator&gt;::value_type</code> verwenden.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2104143</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2104143</guid><dc:creator><![CDATA[ipsec]]></dc:creator><pubDate>Tue, 09 Aug 2011 20:36:02 GMT</pubDate></item><item><title><![CDATA[Reply to Linker: Templates + .cpp Datei = böse? on Tue, 09 Aug 2011 20:43:46 GMT]]></title><description><![CDATA[<p>ipsec schrieb:</p>
<blockquote>
<p>Kleine Anmerkung zum Code: statt <code>InputIterator::value_type</code> solltest du besser <code>std::iterator_traits&lt;InputIterator&gt;::value_type</code> verwenden.</p>
</blockquote>
<p>weshalb ?</p>
<p>Meep Meep</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2104147</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2104147</guid><dc:creator><![CDATA[Meep Meep]]></dc:creator><pubDate>Tue, 09 Aug 2011 20:43:46 GMT</pubDate></item><item><title><![CDATA[Reply to Linker: Templates + .cpp Datei = böse? on Tue, 09 Aug 2011 20:47:23 GMT]]></title><description><![CDATA[<p>Weil auch reine Pointer als Iteratoren verwendet werden könnten - und die haben keine Typedefs für Werttyp etc. (iterator_traits&lt;&gt; sammelt diese Hilfstypen je Iteratorklasse - die Standardversion verwendet It::value_type etc, aber eine Spezialisierung für Pointer überschreibt die Angaben)</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2104150</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2104150</guid><dc:creator><![CDATA[CStoll]]></dc:creator><pubDate>Tue, 09 Aug 2011 20:47:23 GMT</pubDate></item><item><title><![CDATA[Reply to Linker: Templates + .cpp Datei = böse? on Tue, 09 Aug 2011 20:57:11 GMT]]></title><description><![CDATA[<p>Der Standard schreibt vor dass <code>std::iterator_traits&lt;InputIterator&gt;::value_type</code> funktionieren muss.<br />
Er schreibt nicht vor dass <code>InputIterator::value_type</code> funktionieren muss (und funktioniert auch nicht, z.B. für Zeiger wie CStoll schon geschrieben hat).</p>
<p>Und man sollte sinnvollerweise das verwenden, was laut Standard funktionieren muss, und nicht das, was bloss zufälligerweise manchmal funktioniert.</p>
<p>EDIT: sollte man nicht überhaupt <code>std::iterator_traits&lt;InputIterator&gt;::pointer</code> statt <code>std::iterator_traits&lt;InputIterator&gt;::value_type*</code> verwenden?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2104151</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2104151</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Tue, 09 Aug 2011 20:57:11 GMT</pubDate></item><item><title><![CDATA[Reply to Linker: Templates + .cpp Datei = böse? on Wed, 10 Aug 2011 06:45:08 GMT]]></title><description><![CDATA[<p>hustbaer schrieb:</p>
<blockquote>
<p>EDIT: sollte man nicht überhaupt <code>std::iterator_traits&lt;InputIterator&gt;::pointer</code> statt <code>std::iterator_traits&lt;InputIterator&gt;::value_type*</code> verwenden?</p>
</blockquote>
<p>Ja, sollte man <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>
]]></description><link>https://www.c-plusplus.net/forum/post/2104229</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2104229</guid><dc:creator><![CDATA[pumuckl]]></dc:creator><pubDate>Wed, 10 Aug 2011 06:45:08 GMT</pubDate></item><item><title><![CDATA[Reply to Linker: Templates + .cpp Datei = böse? on Wed, 10 Aug 2011 07:08:16 GMT]]></title><description><![CDATA[<p>Gibts dafür einen Grund? In der Funktion selbst werfe ich ja sowieso Zeiger rein.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2104241</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2104241</guid><dc:creator><![CDATA[314159265358979]]></dc:creator><pubDate>Wed, 10 Aug 2011 07:08:16 GMT</pubDate></item><item><title><![CDATA[Reply to Linker: Templates + .cpp Datei = böse? on Wed, 10 Aug 2011 07:32:51 GMT]]></title><description><![CDATA[<p>314159265358979 schrieb:</p>
<blockquote>
<p>Gibts dafür einen Grund? In der Funktion selbst werfe ich ja sowieso Zeiger rein.</p>
</blockquote>
<p>Wenn du irgendwo in dem Funktionstemplates etwas machst, das nur mit rohen Zeigern funktioniert, dann kannst du auch value_type* lassen. Wenn (rein theoretisch) InputIterator::pointer auch ein anderer pointer-Typ sein kann und das dem Funktioniere des Templates keinen Abbruch tut, dann wäre es unnötig, durch Einschränkung des Typen auf value_type* die Verwendbarkeit einzuschränken.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2104250</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2104250</guid><dc:creator><![CDATA[pumuckl]]></dc:creator><pubDate>Wed, 10 Aug 2011 07:32:51 GMT</pubDate></item><item><title><![CDATA[Reply to Linker: Templates + .cpp Datei = böse? on Wed, 10 Aug 2011 08:12:14 GMT]]></title><description><![CDATA[<p><code>std::iterator_traits&lt;InputIterator&gt;::pointer</code> kommt doch ursprünglich von dem ganzen near/far Gedöns, nicht?<br />
Wobei man natürlich auch Smart-Pointer erlauben könnte.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2104277</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2104277</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Wed, 10 Aug 2011 08:12:14 GMT</pubDate></item><item><title><![CDATA[Reply to Linker: Templates + .cpp Datei = böse? on Wed, 10 Aug 2011 17:38:57 GMT]]></title><description><![CDATA[<p>Der Standard erlaubt gar keine proxies in den Containern (mal vom Beschiss in vector&lt;bool&gt; abgesehen). Daher muss eigentlich(!) pointer_type = value_type* sein, genauso wie reference_type = value_type* (wie gesagt, bis auf den beschiss in vector&lt;bool&gt;). Ausserdem gibt kein container irgendwo pointer_type zurück. von daher...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2104566</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2104566</guid><dc:creator><![CDATA[otze]]></dc:creator><pubDate>Wed, 10 Aug 2011 17:38:57 GMT</pubDate></item><item><title><![CDATA[Reply to Linker: Templates + .cpp Datei = böse? on Wed, 10 Aug 2011 18:07:34 GMT]]></title><description><![CDATA[<p>Hast du schonmal daran gedacht, daß auch Dinge außerhalb des C++ Standards existieren, die in der Lage sind, STL-taugliche Iteratoren zu liefern?</p>
<p>(PS: Wenn schon, dann ist reference == value_type&amp; ;))</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2104593</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2104593</guid><dc:creator><![CDATA[CStoll]]></dc:creator><pubDate>Wed, 10 Aug 2011 18:07:34 GMT</pubDate></item><item><title><![CDATA[Reply to Linker: Templates + .cpp Datei = böse? on Wed, 10 Aug 2011 19:23:00 GMT]]></title><description><![CDATA[<p>314159265358979 schrieb:</p>
<blockquote>
<p>pimpl kommt nicht in Frage, dafür ist eine Heap-Allokation erforderlich, und die ist zu teuer.</p>
</blockquote>
<p>Manchmal kommst du um Pimpl nicht herum, wenn du Abhängigkeiten verringern willst. Verwende in diesen Fällen einen speziellen Allokator.</p>
<p>pumuckl schrieb:</p>
<blockquote>
<p>Das war &quot;export&quot;, was das Gegenteil von neu, nämlich deprecated ist.</p>
</blockquote>
<p>&quot;removed&quot; triffts besser, <code>export</code> ist bald Geschichte <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>
]]></description><link>https://www.c-plusplus.net/forum/post/2104629</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2104629</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Wed, 10 Aug 2011 19:23:00 GMT</pubDate></item><item><title><![CDATA[Reply to Linker: Templates + .cpp Datei = böse? on Wed, 10 Aug 2011 22:05:29 GMT]]></title><description><![CDATA[<p>otze schrieb:</p>
<blockquote>
<p>Der Standard erlaubt gar keine proxies in den Containern (mal vom Beschiss in vector&lt;bool&gt; abgesehen). (...)</p>
</blockquote>
<p>Wer spricht denn von Proxies?</p>
<p><code>Referenz != Zeiger</code><br />
<code>std::iterator_traits&lt;T&gt;::reference != std::iterator_traits&lt;T&gt;::pointer</code></p>
<p>IIRC gibt es keine Container-Funktionen die einen Zeiger zurückliefern würden. Von daher kann es auch keine &quot;Proxy-Zeiger&quot; geben.<br />
Trotzdem ermöglicht <code>std::iterator_traits&lt;T&gt;::pointer</code> es z.B. einen <code>T __far*</code> statt eines einfachen <code>T*</code> zu verwenden.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2104659</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2104659</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Wed, 10 Aug 2011 22:05:29 GMT</pubDate></item></channel></rss>