能否实现用于检查编译期固定集合成员关系的中缀运算符is_in?
实现类似
is_in的成员检查逻辑 完全可以实现你想要的功能,C虽然没有内置的is_in中缀运算符,但通过自定义函数、运算符重载或利用现代C特性,能轻松实现接近目标语法的写法,以下是几种可行方案:
1. 基础自定义函数(最直接)
写一个模板函数接受目标值和候选集合(支持初始化列表),利用标准库的查找算法实现:
#include <algorithm> #include <initializer_list> template<typename T> bool is_in(const T& value, std::initializer_list<T> candidates) { return std::find(candidates.begin(), candidates.end(), value) != candidates.end(); }
调用方式:
if (is_in(my_foo, {foo1, foo2, foo3, foo4})) { do_stuff(); }
这种写法简单直观,兼容C++11及以上版本,只要Foo类型支持operator==即可。
2. 模拟中缀运算符(更贴近目标语法)
C++不允许直接定义新的中缀运算符,但可以通过运算符重载组合出类似效果,比如借助代理类实现*in*形式的调用:
#include <algorithm> #include <initializer_list> template<typename T> struct InChecker { const T& target; explicit InChecker(const T& val) : target(val) {} }; constexpr struct InMarker {} in; // 左操作数绑定目标值 template<typename T> InChecker<T> operator*(const T& value, InMarker) { return InChecker<T>(value); } // 右操作数处理候选集合 template<typename T> bool operator*(const InChecker<T>& checker, std::initializer_list<T> candidates) { return std::find(candidates.begin(), candidates.end(), checker.target) != candidates.end(); }
调用方式完美贴近你的预期:
if (my_foo *in* {foo1, foo2, foo3, foo4}) { do_stuff(); }
3. 编译期优化版本(针对固定集合)
如果候选集合是编译期确定的,可以用constexpr数组配合编译期函数,让编译器做更高效的优化:
#include <array> template<typename T, std::size_t N> constexpr bool is_in(const T& value, const std::array<T, N>& candidates) { for (const auto& elem : candidates) { if (elem == value) return true; } return false; }
调用前先定义编译期集合:
constexpr std::array<Foo, 4> candidates = {foo1, foo2, foo3, foo4}; if (is_in(my_foo, candidates)) { do_stuff(); }
对于枚举这类可转换为整数的类型,还可以进一步优化为编译期位掩码检查,效率更高。
关键前提
无论哪种方案,Foo类型必须支持相等性比较:如果是自定义类/结构体,需要手动重载operator==,或者在函数中替换为自定义比较逻辑。
内容的提问来源于stack exchange,提问作者einpoklum
相关产品推荐
相关产品推荐

