PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : std::mem_fun()



BLUESCREEN3D
08-05-2007, 21:19
Irgendwie will std::mem_fun() nicht funktionieren :/

Minimalbeispiel:

#include <algorithm>
#include <functional>

struct s
{
void function(int param);

void another_function()
{
int array[3]={0,1,2};

std::for_each(array, &array[3], std::mem_fun<void,int>(&s::function));
}
};
Beim Kompilieren kriege ich diese Fehlermeldung:
error: no matching function for call to ‘mem_fun(void (s::*)(int))’

locus vivendi
09-05-2007, 15:16
Du brauchst beim Aufrufen von mem_fun normalerweise nicht extra die Template-Typargumente mit angeben, weil die normalerweise durch die Art des Aufrufes bestimmt werden. In deinem Fall hast du sie auch Falsch angegeben. Für mem_fun und deine Funktion "s::function(int)" bräuchtest du drei Typen: Rückgabewert, Klasse und Parametertyp. Du hast aber die Klasse weggelassen. Aber wie gesagt, einfach
"std::mem_fun(&s::function)" sollte es auch tun.

BLUESCREEN3D
09-05-2007, 15:48
einfach "std::mem_fun(&s::function)" sollte es auch tun.
Leider nicht:

/usr/lib/gcc/i386-redhat-linux/4.1.1/../../../../include/c++/4.1.1/bits/stl_algo.h: In function ‘_Function std::for_each(_InputIterator, _InputIterator, _Function) [with _InputIterator = int*, _Function = std::mem_fun1_t<void, s, int>]’:
bla.cpp:18: instantiated from here
/usr/lib/gcc/i386-redhat-linux/4.1.1/../../../../include/c++/4.1.1/bits/stl_algo.h:159: error: no match for call to ‘(std::mem_fun1_t<void, s, int>) (int&)’
/usr/lib/gcc/i386-redhat-linux/4.1.1/../../../../include/c++/4.1.1/bits/stl_function.h:655: note: candidates are: _Ret std::mem_fun1_t<_Ret, _Tp, _Arg>::operator()(_Tp*, _Arg) const [with _Ret = void, _Tp = s, _Arg = int]
Falls es hilft: Ich habe gcc version 4.1.1 20070105 (Red Hat 4.1.1-51).

locus vivendi
09-05-2007, 16:37
/usr/lib/gcc/i386-redhat-linux/4.1.1/../../../../include/c++/4.1.1/bits/stl_algo.h: In function ‘_Function std::for_each(_InputIterator, _InputIterator, _Function) [with _InputIterator = int*, _Function = std::mem_fun1_t<void, s, int>]’:
bla.cpp:18: instantiated from here
/usr/lib/gcc/i386-redhat-linux/4.1.1/../../../../include/c++/4.1.1/bits/stl_algo.h:159: error: no match for call to ‘(std::mem_fun1_t<void, s, int>) (int&)’
/usr/lib/gcc/i386-redhat-linux/4.1.1/../../../../include/c++/4.1.1/bits/stl_function.h:655: note: candidates are: _Ret std::mem_fun1_t<_Ret, _Tp, _Arg>::operator()(_Tp*, _Arg) const [with _Ret = void, _Tp = s, _Arg = int]
Das ist schon ein zweiter Fehler, hätte ich eigentlich auch schon vorhin schreiben können. Jetzt fehlt nämlich noch das Objekt für das die Funktion innerhalb von for_each gerufen werden soll. Du brauchst z.B. noch ein bind1st. Also z.B.


std::for_each(array, &array[3], std::bind1st(std::mem_fun(&s::function), &s1) );

Die Binder aus der Standardbibliothek sind nicht so 100%-ig intuitiv. Ich musste auch erstmal nachgucken, dass an bind1st die Addresse des Objektes übergeben werden muss.

In der nächsten Ausgabe des Standards wird es wahrscheinlich neue Binder geben. In der Zwischenzeit könntest du ja hier mal einen Blick raufwerfen:
http://www.boost.org/libs/bind/bind.html
Die finde ich eigentlich recht einfach zu benutzen.

BLUESCREEN3D
09-05-2007, 20:25
std::for_each(array, &array[3], std::bind1st(std::mem_fun(&s::function), &s1) );
Ich musste das &s1 am Ende zwar durch this ersetzen, aber nun geht es - danke.



Die Binder aus der Standardbibliothek sind nicht so 100%-ig intuitiv. Ich musste auch erstmal nachgucken, dass an bind1st die Addresse des Objektes übergeben werden muss.
Wo kann man sowas am besten nachgucken?

locus vivendi
09-05-2007, 21:09
ch musste das &s1 am Ende zwar durch this ersetzen, aber nun geht es - danke.
Argh! Natürlich. Das ist ein Schnippsel von dem was ich hier kurz selber ausprobiert habe. Und da hatte ich eine Objekt namens "s1".




Zitat von locus vivendi Beitrag anzeigen
Die Binder aus der Standardbibliothek sind nicht so 100%-ig intuitiv. Ich musste auch erstmal nachgucken, dass an bind1st die Addresse des Objektes übergeben werden muss.
Wo kann man sowas am besten nachgucken?
Also ich habe in der Dinkumware-Referenz nachgeschaut. Ob das die beste ist, weiß ich aber nicht. Es kann vorkommen, dass dort bereits Erweiterungen des Standards drinn sind, die anderswo noch nicht implemtiert sind. Das sollte man zumindest wissen.
http://www.dinkumware.com/manuals/?manual=compleat&page=functio2.html#mem_fun