<?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[Function objects: Expertenhilfe erwünscht :)]]></title><description><![CDATA[<p>Hallo,</p>
<p>bin gerade dabei einige for-Schlaufen mit for_each zu ersetzen. Dabei hatte ich jetzt schon ein paarmal Probleme der folgenden Art:</p>
<p>Angenommen ich habe einen std::vector aus ...sagen wir Widgets. Und ich habe eine Membermethode meiner Applikation:</p>
<pre><code class="language-cpp">class Widget;
vector&lt;Widget&gt; widgetContainer;

class Application;
void Application::doSomething(const Widget&amp; wg);
</code></pre>
<p>Jetzt möchte ich jedes Element des Containers auf die Memberfunktion doSomething() loslassen. Mit for sieht das dann so aus:</p>
<pre><code class="language-cpp">Application myApp;
...
for (vector&lt;Widget&gt;::const_iterator i = widgetContainer.begin(); 
                                   i != widgetContainer.end(); ++i)
myApp.doSomething(*i);
</code></pre>
<p>Okay, jetzt versuche ich das ganze mit std::for_each:</p>
<pre><code class="language-cpp">Application myApp;
...
for_each(widgetContainer.begin(), 
         widgetContainer.end(),
         std::bind1st(std::mem_fun(&amp;Application::doSomething), &amp;myApp));
</code></pre>
<p>Das geht leider nicht! Falls irgend jemand was damit anfangen kann... diese Compilermeldung bekomme ich ;):</p>
<blockquote>
<p>c:\programme\c++\mingw\bin\..\lib\gcc\mingw32\4.4.0\include\c++\backward\binders.h|117|error: 'typename _Operation::result_type std::binder1st&lt;_Operation&gt;::operator()(typename _Operation::second_argument_type&amp;) const [with _Operation = std::mem_fun1_t&lt;void, MainDialog, const wxString&amp;&gt;]' cannot be overloaded|</p>
</blockquote>
<p>Jetzt habe ich immerhin herausgefunden, dass es kompiliert, wenn ich doSomething per Value übergeben lasse:</p>
<p>void Application::doSomething(const Widget wg);</p>
<p>Nach dieser Rieseneinleitung jetzt meine eigentliche Frage: Wie schaffe ich es, dass das ganze kompiliert und ich meine Referenz behalten kann? (PS: Eine eigene Funktorklasse kommt für mich nicht in Frage, weil da IMHO die obige for-Schleife noch übersichtlicher ist.)</p>
<p>Viele Grüße, ZenJu</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/247952/function-objects-expertenhilfe-erwünscht</link><generator>RSS for Node</generator><lastBuildDate>Thu, 17 Sep 2026 08:02:30 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/247952.rss" rel="self" type="application/rss+xml"/><pubDate>Mon, 17 Aug 2009 23:15:06 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Function objects: Expertenhilfe erwünscht :) on Mon, 17 Aug 2009 23:15:06 GMT]]></title><description><![CDATA[<p>Hallo,</p>
<p>bin gerade dabei einige for-Schlaufen mit for_each zu ersetzen. Dabei hatte ich jetzt schon ein paarmal Probleme der folgenden Art:</p>
<p>Angenommen ich habe einen std::vector aus ...sagen wir Widgets. Und ich habe eine Membermethode meiner Applikation:</p>
<pre><code class="language-cpp">class Widget;
vector&lt;Widget&gt; widgetContainer;

class Application;
void Application::doSomething(const Widget&amp; wg);
</code></pre>
<p>Jetzt möchte ich jedes Element des Containers auf die Memberfunktion doSomething() loslassen. Mit for sieht das dann so aus:</p>
<pre><code class="language-cpp">Application myApp;
...
for (vector&lt;Widget&gt;::const_iterator i = widgetContainer.begin(); 
                                   i != widgetContainer.end(); ++i)
myApp.doSomething(*i);
</code></pre>
<p>Okay, jetzt versuche ich das ganze mit std::for_each:</p>
<pre><code class="language-cpp">Application myApp;
...
for_each(widgetContainer.begin(), 
         widgetContainer.end(),
         std::bind1st(std::mem_fun(&amp;Application::doSomething), &amp;myApp));
</code></pre>
<p>Das geht leider nicht! Falls irgend jemand was damit anfangen kann... diese Compilermeldung bekomme ich ;):</p>
<blockquote>
<p>c:\programme\c++\mingw\bin\..\lib\gcc\mingw32\4.4.0\include\c++\backward\binders.h|117|error: 'typename _Operation::result_type std::binder1st&lt;_Operation&gt;::operator()(typename _Operation::second_argument_type&amp;) const [with _Operation = std::mem_fun1_t&lt;void, MainDialog, const wxString&amp;&gt;]' cannot be overloaded|</p>
</blockquote>
<p>Jetzt habe ich immerhin herausgefunden, dass es kompiliert, wenn ich doSomething per Value übergeben lasse:</p>
<p>void Application::doSomething(const Widget wg);</p>
<p>Nach dieser Rieseneinleitung jetzt meine eigentliche Frage: Wie schaffe ich es, dass das ganze kompiliert und ich meine Referenz behalten kann? (PS: Eine eigene Funktorklasse kommt für mich nicht in Frage, weil da IMHO die obige for-Schleife noch übersichtlicher ist.)</p>
<p>Viele Grüße, ZenJu</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1762612</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1762612</guid><dc:creator><![CDATA[ZenJu]]></dc:creator><pubDate>Mon, 17 Aug 2009 23:15:06 GMT</pubDate></item><item><title><![CDATA[Reply to Function objects: Expertenhilfe erwünscht :) on Tue, 18 Aug 2009 00:04:29 GMT]]></title><description><![CDATA[<p>Schleife.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1762620</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1762620</guid><dc:creator><![CDATA[Schlaufen-Hater]]></dc:creator><pubDate>Tue, 18 Aug 2009 00:04:29 GMT</pubDate></item><item><title><![CDATA[Reply to Function objects: Expertenhilfe erwünscht :) on Tue, 18 Aug 2009 00:10:24 GMT]]></title><description><![CDATA[<pre><code class="language-cpp">Schleife.
</code></pre>
<p>...das heißt?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1762621</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1762621</guid><dc:creator><![CDATA[ZenJu]]></dc:creator><pubDate>Tue, 18 Aug 2009 00:10:24 GMT</pubDate></item><item><title><![CDATA[Reply to Function objects: Expertenhilfe erwünscht :) on Tue, 18 Aug 2009 05:10:13 GMT]]></title><description><![CDATA[<p>Ich habe es eben ausprobiert und es gibt dasselbe Problem. Irgendwo in libstdc++ wird versucht, bei Benutzung von mem_fun eine Elementfunktion operator() zu erzeugen, bei der eine Referenz auf eine Referenz als Parameter erwartet wird. Das geht natürlich schief. Es sieht eigentlich wie ein libstdc++ Bug aus. Zumindest denke ich auch, dass es funktionieren sollte. Vielleicht können die MSVC++ Leute das auch mal ausprobieren und sagen, ob's bei ihnen klappt.</p>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;vector&gt;
#include &lt;functional&gt;
#include &lt;algorithm&gt;
#include &lt;string&gt;

using namespace std;

class A {
public:
	void foo(string const&amp; x);
};

void A::foo(string const&amp; x)
{
	cout &lt;&lt; x &lt;&lt; '\n';
}

int main()
{
	vector&lt;string&gt; v;
	v.push_back(&quot;123&quot;);
	v.push_back(&quot;hello&quot;);
	v.push_back(&quot;world&quot;);
	A a;
	for_each( v.begin(), v.end(),
		bind1st(mem_fun(&amp;A::foo),&amp;a) );
}
</code></pre>
<p>Wenn man allerdings std::tr1::bind benutzt, klappt es</p>
<pre><code class="language-cpp">...
#include &lt;tr1/functional&gt;
...
using std::tr1::bind;
namespace ph = std::tr1::placeholders;
...
    for_each( v.begin(), v.end(),
        bind(&amp;A::foo,&amp;a,ph::_1) );
...
</code></pre>
<p>Gruß,<br />
SP</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1762635</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1762635</guid><dc:creator><![CDATA[Sebastian Pizer]]></dc:creator><pubDate>Tue, 18 Aug 2009 05:10:13 GMT</pubDate></item><item><title><![CDATA[Reply to Function objects: Expertenhilfe erwünscht :) on Tue, 18 Aug 2009 05:40:17 GMT]]></title><description><![CDATA[<p>MSVC 2008 verweigert das auch:</p>
<blockquote>
<p>c:\programme\microsoft visual studio 9.0\vc\include\functional(276) : error C2529: '_Right' : reference to reference is illegal<br />
c:\programme\microsoft visual studio 9.0\vc\include\functional(281) : error C2529: '_Right' : reference to reference is illegal<br />
c:\programme\microsoft visual studio 9.0\vc\include\functional(282) : error C2535: 'void std::binder1st&lt;_Fn2&gt;::operator ()(const std::basic_string&lt;_Elem,_Traits,_Ax&gt; &amp;(&amp;)) const' : member function already defined or declared</p>
</blockquote>
<p>Es gibt wohl keine Lösung ohne boost oder TR1:</p>
<p><a href="http://groups.google.com/group/comp.lang.c++/browse_thread/thread/a69796bae937c13b/bf00bef79a621573?hl=en" rel="nofollow">http://groups.google.com/group/comp.lang.c++/browse_thread/thread/a69796bae937c13b/bf00bef79a621573?hl=en</a></p>
]]></description><link>https://www.c-plusplus.net/forum/post/1762637</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1762637</guid><dc:creator><![CDATA[MFK]]></dc:creator><pubDate>Tue, 18 Aug 2009 05:40:17 GMT</pubDate></item><item><title><![CDATA[Reply to Function objects: Expertenhilfe erwünscht :) on Tue, 18 Aug 2009 06:03:24 GMT]]></title><link>https://www.c-plusplus.net/forum/post/1762641</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1762641</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Tue, 18 Aug 2009 06:03:24 GMT</pubDate></item><item><title><![CDATA[Reply to Function objects: Expertenhilfe erwünscht :) on Tue, 18 Aug 2009 06:26:28 GMT]]></title><description><![CDATA[<p>Hmmm.... Das müsste doch aber möglich sein. Man kann ja statt</p>
<pre><code class="language-cpp">result_type operator()(typename Operation::second_argument&amp;);
</code></pre>
<p>die Elementfunktion von binder1st auch einfach anders deklarieren:</p>
<pre><code class="language-cpp">result_type operator()(typename add_reference&lt;
    typename Operation::second_argument&gt;::type&amp;);
</code></pre>
<p>wobei add_reference so aussieht:</p>
<pre><code class="language-cpp">template&lt;class T&gt; struct add_reference{typedef T&amp; type;};
template&lt;class T&gt; struct add_reference&lt;T&amp;&gt;{typedef T&amp; type;};
</code></pre>
<p>Ich sehe jetzt zumindest nicht, warum es dann nicht funktionieren soll. Es kann natürlich sein, dass der Standard den ersten Fall vorschreibt. Dann wäre es meiner Meinung nach ein Defekt des Standards.</p>
<p>(Naja, mit std::bind (C++0x) wird sich das sowieso erledigt haben.)</p>
<p>Gruß,<br />
SP</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1762647</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1762647</guid><dc:creator><![CDATA[Sebastian Pizer]]></dc:creator><pubDate>Tue, 18 Aug 2009 06:26:28 GMT</pubDate></item><item><title><![CDATA[Reply to Function objects: Expertenhilfe erwünscht :) on Tue, 18 Aug 2009 07:37:39 GMT]]></title><description><![CDATA[<p>Sebastian Pizer schrieb:</p>
<blockquote>
<p>Es kann natürlich sein, dass der Standard den ersten Fall vorschreibt.</p>
</blockquote>
<p>Tut er.</p>
<p>Sebastian Pizer schrieb:</p>
<blockquote>
<p>Dann wäre es meiner Meinung nach ein Defekt des Standards.</p>
</blockquote>
<p>So ist es.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1762676</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1762676</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Tue, 18 Aug 2009 07:37:39 GMT</pubDate></item><item><title><![CDATA[Reply to Function objects: Expertenhilfe erwünscht :) on Tue, 18 Aug 2009 08:12:59 GMT]]></title><description><![CDATA[<p>möglicherweise funktioniert es so:</p>
<pre><code class="language-cpp">#include &lt;functional&gt;
namespace std
{
    template &lt;class S, class T, class A&gt;
    class mem_fun1_t&lt;S, T, A&amp;&gt;
        : public binary_function&lt;T*, A, S&gt;
    {
        S (T::*op)(A&amp;);
    public:
        explicit mem_fun1_t(S (T::*p)(A&amp;)) : op(p) {}
        S operator()(T* p, A&amp; x) const { return (p-&gt;*op)(x); }
    };
}
</code></pre>
<p>Das ist fast legal (eigentlich müsste ein UDT involviert sein).<br />
Die Idee ist, statt das Referenz-auf-Referenz-Problem zu lösen, Referenzen als Argumente gar nicht erst (offiziell=second_argument) entstehen zu lassen.<br />
Feedback?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1762692</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1762692</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Tue, 18 Aug 2009 08:12:59 GMT</pubDate></item><item><title><![CDATA[Reply to Function objects: Expertenhilfe erwünscht :) on Tue, 18 Aug 2009 10:52:01 GMT]]></title><description><![CDATA[<blockquote>
<p>Irgendwo in libstdc++ wird versucht, bei Benutzung von mem_fun eine Elementfunktion operator() zu erzeugen, bei der eine Referenz auf eine Referenz als Parameter erwartet wird. Das geht natürlich schief</p>
</blockquote>
<p>Das habe ich auch gesehen. Aber ich verstehe nicht, dass mem_fun diesen Fall nicht unterstützt. In meinen Programmen wird jeder zweite Parameter (const Foo&amp;) übergeben. Sowas MUSS doch den Leuten, die mem_fun programmiert haben aufgefallen sein... <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>-ZenJu</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1762791</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1762791</guid><dc:creator><![CDATA[ZenJu]]></dc:creator><pubDate>Tue, 18 Aug 2009 10:52:01 GMT</pubDate></item><item><title><![CDATA[Reply to Function objects: Expertenhilfe erwünscht :) on Tue, 18 Aug 2009 12:32:21 GMT]]></title><description><![CDATA[<p>ZenJu schrieb:</p>
<blockquote>
<blockquote>
<p>Irgendwo in libstdc++ wird versucht, bei Benutzung von mem_fun eine Elementfunktion operator() zu erzeugen, bei der eine Referenz auf eine Referenz als Parameter erwartet wird. Das geht natürlich schief</p>
</blockquote>
<p>Das habe ich auch gesehen. Aber ich verstehe nicht, dass mem_fun diesen Fall nicht unterstützt. In meinen Programmen wird jeder zweite Parameter (const Foo&amp;) übergeben. Sowas MUSS doch den Leuten, die mem_fun programmiert haben aufgefallen sein... <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>-ZenJu</p>
</blockquote>
<p>Dieser Teil des Standards wurde zu einem Zeitpunkt aufgenommen, als praktisch noch kein Compiler in der Lage, mit derartigem Code (Templates) richtig umzugehen. Ein Vielzahl von Fällen wurde also praktisch nur auf dem Papier entworfen und untersucht. Dabei können solche Probleme dann eben durchaus übersehen werden als nur wenige im Standardisierungskomitee Templates wirklich verstanden haben dürften. Und Funktionsadapter sind ja doch schon einer Abstraktionsebene höher als gewöhnliche Container aus T. Schließlich hat es auch bei boost mehrere Jahre und Anläufe gebraucht, bis sie bind richtig hinbekommen haben.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1762852</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1762852</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Tue, 18 Aug 2009 12:32:21 GMT</pubDate></item></channel></rss>