You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何反转通过std::bind绑定的函数的布尔返回值?

如何反转通过std::bind绑定的函数的布尔返回值?

嗨,我完全懂你想要的——一个不用重复写样板代码、能通用反转任意布尔返回值函数结果的方法,不管是直接调用的函数还是std::bind绑定后的对象。先说说你之前尝试遇到的问题,再给你几个实用的解决方案:

为什么你之前的实现和std::bind配合失败?

你写的InvertBooleanResult模板函数之所以报错,是因为std::bind会把整个绑定逻辑包装成一个复杂的_Bind类型 functor,而不是直接把原函数和参数传递给你的模板。当你尝试用std::bind(InvertBooleanResult, IsTheMagicNumber, ...)时,bind会把IsTheMagicNumber当作第一个参数传给InvertBooleanResult,而不是把它作为要调用的目标函数,这就导致最终生成的可调用对象签名和NumberValidator(bool(int))完全不匹配,编译器自然会抛出难以读懂的错误。


方案一:用C++17+标准库的std::not_fn(最优解)

其实STL早就为这个需求提供了现成工具——std::not_fn,它专门用来反转谓词的返回值,能适配所有可调用对象(函数指针、bind结果、lambda都可以)。用你的例子来说,代码可以简化成这样:

#include <functional> // 记得包含这个头文件

// 先定义好原绑定的验证器
NumberValidator check_is_magic = std::bind(IsTheMagicNumber, std::placeholders::_1, 42);

// 一行代码反转结果
NumberValidator check_is_not_magic = std::not_fn(check_is_magic);

// 测试验证
std::cout << std::boolalpha << check_is_not_magic(10) << std::endl; // 输出true
std::cout << std::boolalpha << check_is_not_magic(42) << std::endl; // 输出false

这个方法完全不需要自己写额外的反转逻辑,简洁又符合STL规范,是C++17及以上版本的首选。


方案二:自己实现通用反转工具(兼容C++11/14)

如果还在用C++17之前的版本,没法用std::not_fn,可以自己写一个轻量的通用反转器:

template<typename Func>
struct NotFunctor {
    Func func;

    explicit NotFunctor(Func f) : func(std::move(f)) {}

    template<typename... Args>
    auto operator()(Args&&... args) const -> decltype(!func(std::forward<Args>(args)...)) {
        return !func(std::forward<Args>(args)...);
    }
};

// 辅助推导函数,简化调用
template<typename Func>
NotFunctor<Func> make_not(Func f) {
    return NotFunctor<Func>(std::move(f));
}

使用方式和std::not_fn类似:

NumberValidator check_is_not_magic = make_not(std::bind(IsTheMagicNumber, std::placeholders::_1, 42));

这个实现用了完美转发和自动类型推导,能适配任意参数列表的布尔返回值函数。


方案三:用lambda的简洁写法(无需额外工具)

虽然你更倾向于bind的方式,但lambda其实也能写出非常简洁的代码,而且可读性拉满:

// 直接基于原函数反转
NumberValidator check_is_not_magic = [magic=42](int number) {
    return !IsTheMagicNumber(number, magic);
};

// 或者基于已有的check_is_magic反转
NumberValidator check_is_not_magic = [&check_is_magic](int number) {
    return !check_is_magic(number);
};

这种方式在C++11及以上都能用,不需要理解复杂的bind或模板细节,也是很实用的选择。

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.07 10:44:51