How to cancel a predicate function using an operator! in c ++?

I want to remove all items that do not meet the criteria. For example: delete all characters in a string that is not a number. My solution using boost :: is_digit worked well.

struct my_is_digit { bool operator()( char c ) const { return c >= '0' && c <= '9'; } }; int main() { string s( "1a2b3c4d" ); s.erase( remove_if( s.begin(), s.end(), !boost::is_digit() ), s.end() ); s.erase( remove_if( s.begin(), s.end(), !my_is_digit() ), s.end() ); cout << s << endl; return 0; } 

Then I tried my own version, the compiler complained :( error C2675: unary '!': 'My_is_digit' does not define this operator or conversion to a type acceptable for a predefined operator

I could use the not1 () adapter, but I still think the operator! more significant in my current context. How could I realize that! like boost :: is_digit ()? Any idea?

Update

Follow the instructions of Charles Bailey, I received this piece of code, however, the output is nothing:

 struct my_is_digit : std::unary_function<bool, char> { bool operator()( char c ) const { return isdigit( c ); } }; std::unary_negate<my_is_digit> operator !( const my_is_digit& rhs ) { return std::not1( rhs ); } int main() { string s( "1a2b3c4d" ); //s.erase( remove_if( s.begin(), s.end(), !boost::is_digit() ), s.end() ); s.erase( remove_if( s.begin(), s.end(), !my_is_digit() ), s.end() ); cout << s << endl; return 0; } 

Any idea what is wrong?

Thanks,
Chan

+4
source share
2 answers

You can use std::not1 .

 std::unary_negate<my_is_digit> operator!( const my_is_digit& x ) { return std::not1( x ); } 

To do this, you need #include <functional> and get your my_is_digit functor from the utility std::unary_function< char, bool > . This is just a typedef helper and does not add an extra invoice to your functor.


Full working example:

 #include <string> #include <algorithm> #include <functional> #include <iostream> #include <ostream> struct my_is_digit : std::unary_function<char, bool> { bool operator()(char c) const { return c >= '0' && c <= '9'; } }; std::unary_negate<my_is_digit> operator!( const my_is_digit& x ) { return std::not1( x ); } int main() { std::string s( "1a2b3c4d" ); s.erase( std::remove_if( s.begin(), s.end(), !my_is_digit() ), s.end() ); std::cout << s << std::endl; return 0; } 
+11
source

How could I realize that! e.g. boost :: is_digit ()

... presumably, could you look at the code that forms the implementation of is_digit ? You will see predicate_facade and the corresponding code:

 template<typename PredT> inline detail::pred_notF<PredT> operator!( const predicate_facade<PredT>& Pred ) { // Doing the static_cast with the pointer instead of the reference // is a workaround for some compilers which have problems with // static_cast of template references, ie CW8. /grafik/ return detail::pred_notF<PredT>(*static_cast<const PredT*>(&Pred)); } 
+2
source

Source: https://habr.com/ru/post/1334048/


All Articles