如何使用运算符否定谓词函数!在C ++中?

时间:2011-01-03 09:21:39

标签: c++ stl

我想删除所有不符合标准的元素。例如:删除字符串中不是数字的所有字符。我使用boost :: is_digit的解决方案效果很好。

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;
}

然后我尝试了自己的版本,编译器抱怨:( 错误C2675:一元'!' :'my_is_digit'未定义此运算符或转换为预定义运算符可接受的类型

我可以使用not1()适配器,但我仍然认为操作员!在我目前的背景下更有意义。我怎么能实现这样的!喜欢boost :: is_digit()?有什么想法吗?

更新

按照Charles Bailey的指示,我编译了这段代码片段,但输出结果没有:

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;
}

知道出了什么问题吗?

谢谢,

2 个答案:

答案 0 :(得分:11)

您应该可以使用std::not1

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

要实现此功能,您必须#include <functional>并从实用程序类my_is_digit派生您的std::unary_function< char, bool >仿函数。这纯粹是一个typedef助手,并且不会给你的仿函数增加运行时开销。


完整的工作示例:

#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;
}

答案 1 :(得分:2)

  

我怎么能实现这样的!比如boost :: is_digit()

...大概你可以查看构成is_digit实现的代码吗?您会看到predicate_facade和相关代码:

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's of template references, i.e. CW8. /grafik/
return detail::pred_notF<PredT>(*static_cast<const PredT*>(&Pred)); 
}