Forum: PC-Programmierung copy_if


von Tom (Gast)


Lesenswert?

Habe folgende Templatefunktion:

template <typename Input, typename output typename Predicate>
output copy_if (Input first,Input last,output result,Predicate Pred)
{

   remove_copy_if(first,last,result,Pred);




}
Wie kann ich jetzt das Prädikat Pred negieren,dass aus remove_copy_if 
ein copy_if wird?
Habe schon alles ausprobiert not1,!...

von Simon K. (simon) Benutzerseite


Lesenswert?


von Christoph _. (chris)


Lesenswert?

Zuerst einmal das wichtigste: Deinem Code fehlt die Konsistenz.
Manche template-Typen beginnen bei dir mit einem Großbuchstaben, andere 
mit einem Kleinbuchstaben, bei Variablen sieht es ähnlich aus.

Durch so einen Stil können sich ganz schnell Fehler einschleichen. Denn 
wer das als "unwichtig" abtut, ist erfahrungsgemäß oft auch in anderen 
Bereichen ungenau.

> Habe schon alles ausprobiert not1,!...

not1 funktioniert bei mir einwandfrei, ohne jede seltsame Syntax:
remove_copy_if(first, last, result, not1(pred));

Hast du die Fehlermeldung gelesen? Vielleicht einen Header vergessen? 
Für deine Funktion benötigst du mindestens die beiden Header, die die 
Dokumentation vorschreibt: Siehe 
http://www.sgi.com/tech/stl/remove_copy_if.html und 
http://www.sgi.com/tech/stl/unary_negate.html .

von Tom (Gast)


Lesenswert?

Habe die beiden Header functional und algorithm inkludiert.

Es kommen immer die Fehlermeldungen:

Error  1  error C2825: '_Fn1': must be a class or namespace when 
followed by '::'  c:\program files\microsoft visual studio 
8\vc\include\functional  205
Error  2  error C2039: 'argument_type' : is not a member of '`global 
namespace''  c:\program files\microsoft visual studio 
8\vc\include\functional  205
Error  3  error C2146: syntax error : missing ',' before identifier 
'argument_type'  c:\program files\microsoft visual studio 
8\vc\include\functional  205
Error  4  error C2065: 'argument_type' : undeclared identifier 
c:\program files\microsoft visual studio 8\vc\include\functional  205


Mein main sieht folgendermaßen aus:


bool isPos(int x)
{

  return x<0;

}

int main ()
{

  int a[]={3,5,-7,-4,8,-9};
  int b[]={4,-6,5,3,8,-9};

  vector<int> v2(b,b+sizeof(b)/sizeof(int));
  vector<int> v3;



  cout <<endl;
  Copy_if(v2.begin(),v2.end(),back_inserter(v3),isPos);
  copy(v3.begin(),v3.end(),ostream_iterator<int>(cout," "));
}

von Christoph _. (chris)


Lesenswert?

> Mein main sieht folgendermaßen aus:
> [...]

Bitte poste mal ein vollständiges, aber minimales Codebeispiel, bei 
dem der Fehler auftritt. Dein Code lässt sich nicht kompilieren, weil 
die Definition von Copy_if (Achtung, großer Anfangs-Buchstabe) fehlt und 
die ganzen Header nicht eingebunden sind. Ein vollständiges Beispiel, 
das man direkt per copy&paste in seinen Editor ziehen und testweise 
kompilieren kann, hilft wahrscheinlich eher.

Aus den Fehlermeldungen schließe ich, dass du Visual Studio 2005 
benutzt, ist das korrekt? Hast du eine andere als die Standard-STL 
installiert?

von Tom (Gast)


Lesenswert?

Nein benutze die STL von VisualStudio 2005:

Also
template.h:

#include <algorithm>
#include <iterator>
#include <functional>

using namespace std;

template <typename TInputItor,typename TOutputItor,typename TPred>
void Copy_if(TInputItor first,TInputItor last,TOutputItor result,TPred 
Pred)
{


  remove_copy_if(first,last,result,not1(Pred));



}
-----------------------------------------------------------
main.cpp:


#include "template.h"
#include <iostream>
#include <vector>
#include <iterator>

using namespace std;

bool isPos(int x)
{

  return x<0;

}

int main ()
{


  int b[]={4,-6,5,3,8,-9};

  vector<int> v2(b,b+sizeof(b)/sizeof(int));
  vector<int> v3;


  cout <<endl;
  Copy_if(v2.begin(),v2.end(),back_inserter(v3),isPos);
  copy(v3.begin(),v3.end(),ostream_iterator<int>(cout," "));
}

von Rolf Magnus (Gast)


Lesenswert?

isPos ist kein Funktionsobjekt, sondern eine normale Funktion. Damit 
geht not1 nicht.

Probier mal:
1
struct isPos : std::unary_function<int, bool>
2
{
3
    bool operator()(int x) const 
4
    {
5
      return x<0;
6
    }
7
};
8
9
Copy_if(v2.begin(),v2.end(),back_inserter(v3),isPos());

Oder:
1
Copy_if(v2.begin(),v2.end(),back_inserter(v3),
2
        std::bind2nd(std::less<int>(), 0));

von Tom (Gast)


Lesenswert?

Danke hat funktioniert!

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.