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

能否实现用于检查编译期固定集合成员关系的中缀运算符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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 05:01:02