能否将基础运算符<作为可调用参数传入?C++实现方案咨询
问题
我的底层程序需要一个参数,用于指定使用小于(<)或大于(>)运算符比较数据。现有实现如下:
using CompOp_f = std::function<bool( double, double )>; struct LowLevelObj_t { bool doChecking() { return _op( _x, _y ); }; CompOp_f _op; double _x; double _y; };
使用时需通过lambda表达式赋值:
LowLevelObj_t a { ._op = []( double l_, double r_ ) { return l_ < r_; }, ._x = -1., ._y = 1., }; // 使用小于运算符时 bool pos_result = a.doChecking(); // 使用大于运算符时 a._op = []( double l_, double r_ ) { return l_ > r_; }; bool neg_result = a.doChecking();
我希望直接这样实现:
// 使用小于运算符时 a._op = <; bool pos_result = a.doChecking(); // 使用大于运算符时 a._op = >; bool neg_result = a.doChecking();
这样既提升可读性,又能减少lambda对象带来的额外开销。请问是否有可行的实现方式?如何实现?我知道可以用模板语法,但会因需特化LowLevelObj_t而重复编写复杂的doChecking()逻辑,因此不希望采用该方案。
解决方案
完全可以实现类似的简洁写法,不需要模板特化,核心是利用C++标准库提供的预定义函数对象,同时优化赋值语法:
步骤1:替换lambda为标准库函数对象
C++标准库<functional>头文件中已经提供了std::less<double>和std::greater<double>预定义函数对象,它们分别对应<和>运算符逻辑,且是轻量空对象,无lambda的额外开销。
步骤2:简化赋值语法
以下两种方法可以实现接近你需求的简洁写法:
方法一:定义全局常量(最简单易用)
把标准库函数对象封装成全局常量,赋值时语义清晰、写法简洁:
#include <functional> // 定义全局常量,对应<和>运算符 constexpr std::less<double> less_op; constexpr std::greater<double> greater_op; using CompOp_f = std::function<bool( double, double )>; struct LowLevelObj_t { bool doChecking() { return _op( _x, _y ); }; CompOp_f _op; double _x; double _y; }; // 使用示例 int main() { LowLevelObj_t a { ._op = less_op, ._x = -1., ._y = 1., }; // 使用小于运算符时 bool pos_result = a.doChecking(); // 使用大于运算符时 a._op = greater_op; bool neg_result = a.doChecking(); }
这种写法不需要修改原有结构体核心逻辑,完全复用doChecking(),同时消除了lambda的额外开销,可读性也大幅提升。
方法二:重载赋值运算符(更贴近理想写法)
如果想更接近a._op = <;的形式,可以通过自定义枚举+重载赋值运算符实现:
#include <functional> // 定义枚举表示比较运算符类型 enum class CompOp { Less, Greater }; // 为std::function<bool(double,double)>重载赋值运算符 std::function<bool(double,double)>& operator=(std::function<bool(double,double)>& func, CompOp op) { switch(op) { case CompOp::Less: func = std::less<double>(); break; case CompOp::Greater: func = std::greater<double>(); break; } return func; } // 定义全局常量替代枚举值,贴近目标写法(注意符号需加空格避免语法错误) constexpr CompOp <_ = CompOp::Less; constexpr CompOp >_ = CompOp::Greater; using CompOp_f = std::function<bool( double, double )>; struct LowLevelObj_t { bool doChecking() { return _op( _x, _y ); }; CompOp_f _op; double _x; double _y; }; // 使用示例 int main() { LowLevelObj_t a { ._op = CompOp::Less, ._x = -1., ._y = 1., }; // 使用小于运算符时 a._op = <_; bool pos_result = a.doChecking(); // 使用大于运算符时 a._op = >_; bool neg_result = a.doChecking(); }
注:<和>是C++保留符号,无法直接作为变量名,因此这里用<_和>_替代,避免语法错误。
核心优势
- 无需模板特化,完全复用原有
doChecking()逻辑,避免代码重复; - 标准库函数对象比lambda更轻量,调用开销更小;
- 写法简洁直观,可读性显著提升。
内容的提问来源于stack exchange,提问作者Leon
相关产品推荐
相关产品推荐

