c++ - C++ 中的模板化 is_in() 函数(检查数组是否包含字符串)
问题描述
我想做以下事情:
std::string b = "b";
is_in("a", { "a", "b", "c" });
is_in("d", { "a", "b", "c" });
is_in(b, { "a", "b", "c" }); // fails
is_in(b, std::array{ "a", "b", "c" });
使用模板
template<typename Element, typename Container>
bool is_in(const Element& e, const Container& c)
{
// https://stackoverflow.com/questions/20303821/how-to-check-if-string-is-in-array-of-strings
return std::find(std::begin(c), std::end(c), e) != std::end(c);
}
template<typename Element>
bool is_in(Element e, std::initializer_list<Element> l)
{
// return std::find(std::begin(l), std::end(l), e) != std::end(l);
return is_in<Element, std::initializer_list<Element>>(e, l);
}
但我收到以下错误(使用 GCC 9.3.0):
no matching function for call to ‘is_in(std::string&, <brace-enclosed initializer list>)’
那里有任何大脑模板的家伙有建议吗?
解决方案
对于is_in(b, { "a", "b", "c" });
, 模板形参Element
推导为std::string
第一个参数b
,推导为const char*
第二个参数{ "a", "b", "c" }
;他们不匹配。
您可以为 提供两个模板参数is_in
,例如
template<typename E1, typename E2>
bool is_in(E1 e, std::initializer_list<E2> l)
{
// return std::find(std::begin(l), std::end(l), e) != std::end(l);
return is_in<E1, std::initializer_list<E2>>(e, l);
}
或者使用std::type_identity
(从 C++20 开始;并且很容易为 C++20 之前的版本编写一个)从类型推导中排除第二个函数参数。
template<typename Element>
bool is_in(Element e, std::initializer_list<std::type_identity_t<Element>> l)
{
// return std::find(std::begin(l), std::end(l), e) != std::end(l);
return is_in<Element, std::initializer_list<Element>>(e, l);
}
推荐阅读
- vba - 从页面本身更新页面的标题
- vue.js - 使用 v-model 更改单个值/重新绘制完整表
- android - 当键盘以模态打开时,模态在真实的android设备中关闭
- email - 如何创建一个自动从 Google 表格中获取数据并替换幻灯片模板中的标签的函数?
- java - GZIPInputStream:无法逐行正确读取在线 .gz 文件
- cassandra - 尝试从 DSE Cassandra(6.0.5) 迁移到 Apache Cassandra(3.11.3) 时出现架构版本不匹配错误
- javascript - 如何在保留单个连字符分隔符规则的同时从带连字符的序列键中删除无效字符?
- groovy - 使用 MS Graph API 与 MS Azure SDK 的主要广告和缺点是什么
- laravel - 二选动态vue laravel
- c# - 我可以知道我的应用是否允许与 UWP 中未配对的设备配对吗?