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

C++折叠表达式实现参数包布尔运算及自动类型推导优化

问题分析

你的原代码核心问题有两个:一是必须显式指定模板类型T,无法自动推导;二是折叠表达式里的|| ... || false属于冗余写法——C++折叠表达式对||的空参数包默认结果就是false,直接写((ts == value) || ...)即可。

下面分别给出C17和C20的可行方案:

C++17 实现方案

C++17不支持auto作为非类型模板参数的类型,要省去显式指定T需要一些技巧,分两种场景:

场景1:候选值仍作为模板参数传递

我们可以用宏自动推导T的类型,避免手动写<int>这类标注:

#include <type_traits>

template<typename T, T... Ts>
constexpr bool is_in(T value) {
    // 折叠表达式:逐个匹配,只要有一个相等就返回true
    return ((Ts == value) || ...);
}

// 宏自动推导T为输入值的类型
#define IS_IN(value, ...) is_in<decltype(value), __VA_ARGS__>(value)

int main() {
    if constexpr(IS_IN(1, 1, 2, 3)) {
        return 10; // 会执行,因为1在候选列表里
    }
    return 0;
}

场景2:候选值作为函数参数传递

如果允许把候选值放在函数参数里,就能直接实现自动类型推导,同时用static_assert确保所有候选值类型和输入值一致:

#include <type_traits>

template<typename T, typename... Args>
constexpr bool is_in(T value, Args... args) {
    // 强制所有候选值和输入值类型相同,避免隐式转换导致的意外
    static_assert((std::is_same_v<T, Args> && ...), "所有候选值必须和输入值类型一致");
    return ((args == value) || ...);
}

int main() {
    if constexpr(is_in(1, 1, 2, 3)) {
        return 10;
    }
    return 0;
}
C++20 实现方案

C++20引入了auto非类型模板参数,直接解决了类型推导的问题,写法更加简洁:

严格类型匹配版

用requires约束确保所有候选值和输入值类型完全一致:

#include <concepts>

template<auto... Ts>
constexpr bool is_in(decltype(Ts) value) 
    requires (std::same_as<decltype(Ts), decltype(value)> && ...) {
    return ((Ts == value) || ...);
}

int main() {
    if constexpr(is_in<1, 2, 3>(1)) {
        return 10;
    }
    return 0;
}

宽松类型匹配版(支持隐式转换)

如果允许候选值和输入值进行隐式类型转换(比如is_in<1,2,3>(1.0)),可以去掉约束,用std::common_type_t统一类型:

#include <type_traits>

template<auto... Ts>
constexpr bool is_in(std::common_type_t<decltype(Ts)...> value) {
    return ((Ts == value) || ...);
}

int main() {
    if constexpr(is_in<1, 2, 3>(1)) {
        return 10;
    }
    return 0;
}

内容的提问来源于stack exchange,提问作者Nick

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 10:02:36