Prädikat für die Funktion remove_copy_if negieren
-
Hallo zusammen,
ich möchte für die Funktion remove_copy_if aus dem Namensraum std ein Prädikat negieren. Wie ich recht schnell festgestellt hab, reicht ein einfaches '!' nicht.
Somit habe ich folgendes gebastelt bzw. aus der Literatur entnommen:
Prädikat:
bool isPrim(unsigned int z) { unsigned int stop = sqrt(static_cast<double> (z)); for (unsigned int i = 2; i <= stop; i++) { if (z % i == 0) return false; } return true; }Negator:
template<typename Predicate> UnaryNegate<Predicate> not1(const Predicate &pred) { return UnaryNegate<Predicate> (pred); }Klasse Unary Negate
template<typename Predicate> class UnaryNegate: public unary_function<typename Predicate::argument_type, bool> { public: explicit UnaryNegate(const Predicate &pre) : p(pre) { } virtual ~UnaryNegate(); bool operator()(const typename Predicate::argument_type& x) const { return !p(x); } private: Predicate p; };Und zusammen wie folgt angewandt:
unsigned int numbers[] = { 2, 6, 29, 30, 45, 49, 50 }; //Number of integers int n = sizeof numbers / 4;remove_copy_if(numbers, numbers + n, ostream_iterator<unsigned int> (cout, ","), not1(isPrim));Mein Compiler sagt mir nun folgendes:
**** Build of configuration Debug for project Standardbibiothek Beispiele ****
make all
Building file: ../src/Kapitel3.cpp
Invoking: GCC C++ Compiler
g++ -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"src/Kapitel3.d" -MT"src/Kapitel3.d" -o"src/Kapitel3.o" "../src/Kapitel3.cpp"
/usr/include/c++/4.0.0/bits/stl_function.h: In instantiation of 'std::unary_negate<bool ()(unsigned int)>':
../src/Kapitel3.cpp:106: instantiated from here
/usr/include/c++/4.0.0/bits/stl_function.h:314: error: 'bool ()(unsigned int)' is not a class, struct, or union type
/usr/include/c++/4.0.0/bits/stl_function.h:322: error: 'bool ()(unsigned int)' is not a class, struct, or union type
/usr/include/c++/4.0.0/bits/stl_function.h:316: error: field 'std::unary_negate<bool ()(unsigned int)>::_M_pred' invalidly declared function type
/usr/include/c++/4.0.0/bits/stl_algo.h: In function '_OutputIterator std::remove_copy_if(_InputIterator, _InputIterator, _OutputIterator, _Predicate) [with _InputIterator = unsigned int*, _OutputIterator = std::ostream_iterator<unsigned int, char, std::char_traits<char> >, _Predicate = std::unary_negate<bool ()(unsigned int)>]':
../src/Kapitel3.cpp:106: instantiated from here
/usr/include/c++/4.0.0/bits/stl_algo.h:1074: error: no match for call to '(std::unary_negate<bool ()(unsigned int)>) (unsigned int&)'
make: *** [src/Kapitel3.o] Error 1Mein Problem ist nun, dass ich nicht weiß wie ich das ganze angehen soll bzw. wie man am besten heraus findet, wo der Fehler liegt ohne alles 1 zu 1 abzuschreiben(aus Literatur etc.). Gebt ihr mir einen Tipp?
Viele Grüße
MM
-
du brauchst dir dein negations-Prädikat nicht selber zu schreiben, das gibts in der Standardbibliothek schon, im header <functional>, und es heißt std::not1. Das ist auch das was dein Compiler da benutzt.
Versuch mal, statt isPrim direkt zu übergeben, einen Pointer darauf zu übergeben:remove_copy_if(numbers, numbers + n, ostream_iterator<unsigned int> (cout, ","), not1(&isPrim)); // <-!!!
-
Der Fehler ist einfach und blöd. Man darf keine Funktion übergeben, sondern muss aus der Funktion zuerst ein
pointer_to_unary_functionObjekt erstellen.remove_copy_if(numbers, numbers + n, ostream_iterator<unsigned int> (cout, ","), not1(ptr_fun(isPrim)));Wie du siehst, erreicht man die mit
std::ptr_fun.Unter anderem deshalb freuen sich alle über
Boost.Bind,std::tr1::bindoder dem C++0xstd::bind.Edit: Rechtschreibefehler.
Grüssli

-
super, vielen Dank
Klappt nun.Viele grüße
MM