如何检查类型T是否在C ++中的参数包Ts ...中?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (10)

我想编写一个函数来返回true,如果T是其中之一Ts...

template<class T, class... Ts>
bool is_one_of<T, Ts...>();

例如,is_one_of<int, double, int, float>返回trueis_one_of<int, double, std::string, bool, bool>返回false

我自己的实现是

template<class T1, class T2>
bool is_one_of<T1, T2>() {
    return std::is_same<T1, T2>;
}

template<class T1, class T2, class... Ts>
bool is_one_of<T1, T2, Ts...> {
    if (std::is_same<T1, T2>) {
        return true;
    }
    else {
        return is_one_of<T1, Ts...>();
    }
}

这个检查对我来说很常见,所以我想知道标准库中是否已经存在这样的功能。

提问于
用户回答回答于

在您自己的实现中,一个问题是C ++不允许对函数模板进行部分特化。

您可以使用fold表达式(在C ++ 17中引入)而不是递归函数调用。

template<class T1, class... Ts>
constexpr bool is_one_of() noexcept {
    return (std::is_same_v<T1, Ts> || ...);
}

如果您使用的是折叠表达式并且std::disjunction不可用的C ++ 11 ,您可以这样实现is_one_of

template<class...> struct is_one_of: std::false_type {};
template<class T1, class T2> struct is_one_of<T1, T2>: std::is_same<T1, T2> {};
template<class T1, class T2, class... Ts> struct is_one_of<T1, T2, Ts...>: std::conditional<std::is_same<T1, T2>::value, std::is_same<T1, T2>, is_one_of<T1, Ts...>>::type {};
用户回答回答于

您还可以使用std::disjunction以避免不必要的模板实例化:

template <class T0, class... Ts>
constexpr bool is_one_of = std::disjunction_v<std::is_same<T0, Ts>...>;

找到匹配类型后,不会实例化其余模板。相反,fold表达式实例化所有这些。根据您的使用情况,这可能会导致编译时间的显着差异。

扫码关注云+社区

领取腾讯云代金券