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

发布于 2024-10-09 23:06:26 字数 1242 浏览 0 评论 0原文

我想删除所有不满足标准的元素。例如:删除字符串中所有非数字字符。我使用 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;
}

知道出了什么问题吗?

谢谢,

I want to erase all the elements that do not satisfy a criterion. For example: delete all the characters in a string that are not digit. 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 a conversion to a type acceptable to the predefined operator

I could use not1() adapter, however I still think the operator ! is more meaningful in my current context. How could I implement such a ! like boost::is_digit() ? Any idea?

Update

Follow Charles Bailey's instruction, I got this code snippet compiled, 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 was wrong?

Thanks,
Chan

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

眼泪也成诗 2024-10-16 23:06:26

您应该能够使用 std::not1

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

为此,您必须#include 并从实用程序类std::unary_function派生您的my_is_digit 仿函数。字符,布尔>。这纯粹是一个 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;
}

You should be able to use std::not1.

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

For this to work you have to #include <functional> and derive your my_is_digit functor from the utility class std::unary_function< char, bool >. This is purely a typedef helper and adds no runtime overhead to your functor.


Complete 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;
}
我要还你自由 2024-10-16 23:06:26

我怎样才能实现这样的!就像 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)); 
}

How could I implement such a ! like boost::is_digit()

...presumably you could look at the code that forms the is_digit implementation? You will see predicate_facade and the relevant 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's of template references, i.e. CW8. /grafik/
return detail::pred_notF<PredT>(*static_cast<const PredT*>(&Pred)); 
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文