2016-04-20 10 views
2

Wie sollte ich definieren, Lambda zu nehmen char von string iterator? Im folgenden Code hat Lambda detect_bracket ein Problem mit dem Eingangsparameter x.Lambda zu nehmen `char` Argument

Ich möchte nicht ALLE Klammern aus der Zeichenfolge löschen, nur am Anfang und am Ende.

auto detect_bracket = [](char* x){ return(')' == x || '(' == x);}; 

this->str.erase(std::remove_if(str.begin(), str.begin(), 
      detect_bracket) 
); 
this->str.erase(std::remove_if(str.back(), str.back(), 
      detect_bracket) 
); 
+0

'[] (char x) {return (')' == x || '(' == x);} 'ist nicht ausreichend? – 101010

+0

@ 101010 '/usr/include/c++/4.8/bits/stl_algo.h: In Instantiierung von '_FIter std :: remove_if (_FIter, _FIter, _Predicate) [mit _FIter = char; _Predicate = ExprContainer :: removeBrackets() :: __ lambda0] ': ../src/CMEXPR.cpp:194:20: erforderlich von hier /usr/include/c++/4.8/bits/stl_algo.h:1150:25 : error: ungültiger Typ Argument von unary '*' (hab 'char') ' –

+0

nicht' char * ', sondern' char'. – 101010

Antwort

4

Sie sollten mit std::remove_if, char als Parametertyp des Lambda nehmen, da die Signatur der Prädikatfunktion soll direkt das Element überprüfen.

auto detect_bracket = [](char x){ return(')' == x || '(' == x);}; 
this->str.erase(std::remove_if(str.begin(), str.end(), 
     detect_bracket) 
); 

Hinweis std::string::back() nicht mit std::remove_if arbeiten. Es wird eine char zurückgegeben und std::remove_if erwartet einen Bereich durch Iterator ausgedrückt.

Und str.begin(), str.begin() ist nur ein leerer Bereich, wenn Sie nur an Element entfernen möchten, die beginnen und enden, könnten Sie

auto detect_bracket = [](char x){ return(')' == x || '(' == x);}; 
if (!this->str.empty()) { 
    this->str.erase(std::remove_if(str.begin(), str.begin() + 1, detect_bracket), str.begin() + 1); 
} 
if (!this->str.empty()) { 
    this->str.erase(std::remove_if(str.end() - 1, str.end(), detect_bracket), str.end()); 
} 

Hinweis wir das richtige Ende Iterator für std::string::erase, angeben müssen, weil std::remove_if zurückkehren ein Iterator, auch wenn es nichts gefunden hat, und dann wird der Char falsch gelöscht.

LIVE

+1

' str.begin (), str.end() ' – Muggen

+0

Ich möchte nicht löschen * ALL * Klammern aus der Zeichenfolge, nur am Anfang und am Ende. –

+2

@CronAcronis 'str.begin(), str.begin()' ist ein leerer Bereich, so dass nichts entfernt wird. Vielleicht möchten Sie 'str.begin(), str.begin() + 1' und' str.rbegin(), str.rbegin() + 1'. – songyuanyao

2

std::remove_if ist eine Funktion, mit der folgenden Signatur:

template< class ForwardIt, class UnaryPredicate > 
ForwardIt remove_if(ForwardIt first, ForwardIt last, UnaryPredicate p); 

p - unary predicate which returns ​ true if the element should be removed. The signature of the predicate function should be equivalent to the following:

bool pred(const Type &a); 

The type Type must be such that an object of type ForwardIt can be dereferenced and then implicitly converted to Type. ​

Alles, was Sie brauchen, ist Ihr Funktionsparameter von char* zu char zu ändern.

0

Mehrere remove_if und erase Aufrufe ändern/invalidieren die string. Warum erstellen Sie nicht einfach eine neue string, und weisen Sie die Quellzeichenfolge ab der 0. Stelle oder 1. Stelle bedingt zu? Und dann assign bis zum letzten oder vorletzten Zeichen, bedingt?

Verwandte Themen