<?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[Welche Schnittstelle anbieten: Container oder begin() und end()]]></title><description><![CDATA[<p>Moin,</p>
<p>ich habe ein Objekt Klasse A, die Referenzen/Pointer auf eine Menge (nicht mathematisch) von B-Objekten hält. Darauf brauche ich lesenden Zugriff. Wie<br />
würdet ihr die Schnittstelle gestalten? Was wäre da <em>idiomatisches</em> C++?</p>
<p>Ich tendiere Stark zu Version 2.</p>
<pre><code class="language-cpp">class A {
    // so
    typedef std::vector&lt;const B*&gt;::const_iterator b_iter;
    b_iter b_begin();
    b_iter b_end();

    // oder so?

    const std::vector&lt;const B*&gt;&amp; bes() const;

private:
    std::vector&lt;const B*&gt; internals;
};
</code></pre>
<p>Gruß, Panke</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/275713/welche-schnittstelle-anbieten-container-oder-begin-und-end</link><generator>RSS for Node</generator><lastBuildDate>Mon, 24 Aug 2026 10:10:07 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/275713.rss" rel="self" type="application/rss+xml"/><pubDate>Tue, 19 Oct 2010 19:02:13 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Welche Schnittstelle anbieten: Container oder begin() und end() on Tue, 19 Oct 2010 19:02:13 GMT]]></title><description><![CDATA[<p>Moin,</p>
<p>ich habe ein Objekt Klasse A, die Referenzen/Pointer auf eine Menge (nicht mathematisch) von B-Objekten hält. Darauf brauche ich lesenden Zugriff. Wie<br />
würdet ihr die Schnittstelle gestalten? Was wäre da <em>idiomatisches</em> C++?</p>
<p>Ich tendiere Stark zu Version 2.</p>
<pre><code class="language-cpp">class A {
    // so
    typedef std::vector&lt;const B*&gt;::const_iterator b_iter;
    b_iter b_begin();
    b_iter b_end();

    // oder so?

    const std::vector&lt;const B*&gt;&amp; bes() const;

private:
    std::vector&lt;const B*&gt; internals;
};
</code></pre>
<p>Gruß, Panke</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1967697</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1967697</guid><dc:creator><![CDATA[Panke]]></dc:creator><pubDate>Tue, 19 Oct 2010 19:02:13 GMT</pubDate></item><item><title><![CDATA[Reply to Welche Schnittstelle anbieten: Container oder begin() und end() on Tue, 19 Oct 2010 19:20:40 GMT]]></title><description><![CDATA[<p>Das &quot;defensivste&quot; Interface ist vermutlich <code>template &lt;class OutIt&gt; void get(OutIt outputIterator)</code> . Also nen Getter der alle Elemente in einen Output-Iterator rein<em>kopiert</em>.</p>
<p>Wenn das reicht -&gt; so machen.<br />
Wenn das z.B. zu langsam ist, oder die Objekte nicht kopierbar sind, dann auf jeden Fall eher die begin/end Variante als direkt den Vektor rausreichen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1967716</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1967716</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Tue, 19 Oct 2010 19:20:40 GMT</pubDate></item><item><title><![CDATA[Reply to Welche Schnittstelle anbieten: Container oder begin() und end() on Wed, 20 Oct 2010 06:53:12 GMT]]></title><description><![CDATA[<p>Danke, auf die Idee mit dem OutputIterator wär ich nicht gekommen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1967834</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1967834</guid><dc:creator><![CDATA[Panke]]></dc:creator><pubDate>Wed, 20 Oct 2010 06:53:12 GMT</pubDate></item><item><title><![CDATA[Reply to Welche Schnittstelle anbieten: Container oder begin() und end() on Mon, 03 Jan 2011 22:52:17 GMT]]></title><description><![CDATA[<p>Kann ich sowas auch in einem Interface machen? Also beispielsweise:</p>
<pre><code class="language-cpp">class Item{};

struct Interface {
    typedef std::vector&lt;C&gt;::iterator iter;
    virtual iter begin() = 0;
};

struct Implementation : public Interface {
    typedef std::deque&lt;C&gt;::iterator iter;
    iter begin() { /* ... */ }
};
</code></pre>
<p>So wie oben dargestellt, sagt mir gcc <em>invalid covariant for return type ...</em> . Was ich möchte ist, im Interface nur zu sagen, dass da ein Iterator zurückgegeben wird ohne die Implementierungen auf eine interne Struktur festzulegen. Was mir da einfällt, wäre ein Template. Dann müsste ich aber ein Klassentemplate schreiben, weil Templatemethoden ja nicht virtuell sind.</p>
<p>Alternative: Nutzer der Klassen sind Templates und ich lass das Interface weg. Gefällt mir aber irgendwie auch nicht Recht. Aber noch am besten. Im Grunde ist das für mein Programm nur ein kleineres Problem, ich könnt auch einfach festlegen, welcher Container intern genutzt wird und punkt. Was macht da der Profi?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2002000</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2002000</guid><dc:creator><![CDATA[Panke]]></dc:creator><pubDate>Mon, 03 Jan 2011 22:52:17 GMT</pubDate></item><item><title><![CDATA[Reply to Welche Schnittstelle anbieten: Container oder begin() und end() on Mon, 03 Jan 2011 23:06:38 GMT]]></title><description><![CDATA[<p>Der Typ <code>C</code> ist in <code>Implementation</code> unbekannt.</p>
<blockquote>
<p>nur zu sagen, dass da ein Iterator zurückgegeben wird</p>
</blockquote>
<p>Erben die Standardcontainer von einem Interface mit <code>begin</code> oder <code>end</code> ? Nein. Mache nicht aus der Klasse ein Template sondern aus deinen Algorithmen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2002002</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2002002</guid><dc:creator><![CDATA[knivil]]></dc:creator><pubDate>Mon, 03 Jan 2011 23:06:38 GMT</pubDate></item><item><title><![CDATA[Reply to Welche Schnittstelle anbieten: Container oder begin() und end() on Tue, 04 Jan 2011 00:10:45 GMT]]></title><description><![CDATA[<p>Alles zu templatisieren kann aber auch der falsche Weg sein – besonders wenn es darum geht, Abhängigkeiten von Programmbestandteilen klein zu halten. In diesem Fall kann sich das Konzept der Type Erasure bewähren (siehe z.B. <a href="http://www.artima.com/cppsource/type_erasure.html" rel="nofollow">hier</a>).</p>
<p>Zur Zusammenfassung einiger Möglichkeiten, wie sich eine Schnittstelle zu einem Member-Container gestalten lässt:</p>
<ul>
<li><strong>(Const-)Referenz auf Container</strong> als Rückgabetyp. Schlechte Kapselung, Abstraktion zum Containertyp geht verloren.</li>
<li><strong>Begin-End</strong> als Iterator-Schnittstelle.</li>
<li><strong>Output-Iterator</strong>. Erlaubt aber nur Lesezugriff und erfordert Kopien.</li>
<li><strong>Funktor</strong>, der an eine Memberfunktion <code>apply()</code> übergeben wird und intern mit <code>std::for_each()</code> auf jedes Element des Containers angewandt wird. Kann Veränderungen durchführen oder auch Daten im Funktionsobjekt speichern. Braucht bei der Anwendung jedoch jedes Mal viel Boilerplate-Code, zumindest ohne Lambda-Funktionen.</li>
<li><strong>Polymorpher Basisklassenzeiger</strong> anstelle eines Funktors, mit virtueller Methode statt <code>operator()</code> . Im Prinzip aber gleich wie oben.</li>
<li><strong>Range</strong> als Rückgabetyp. Sehr flexibler Ansatz, auch mit Type Erasure kombinierbar.</li>
</ul>
]]></description><link>https://www.c-plusplus.net/forum/post/2002015</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2002015</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Tue, 04 Jan 2011 00:10:45 GMT</pubDate></item></channel></rss>