包装器包含()函数用于不同的容器
Wrapper contains() function for different containers
受contains()的启发,我想声明contains(),适合杂项容器。
// for std::vector, std::list, .. (1)
template<typename C, typename T>
bool contains(const C& container, const T& val)
{
return ::std::find(container.begin(), container.end(), val) != container.end();
}
// partial specialization for std::map (2)
template<typename K, typename V>
bool contains(const ::std::map<K, V>& container, const K& key)
{
// std::map.find() is better than std::find used in (1)
return container.find(key) != container.end();
}
以下问题,我想将函数添加到参数所属的命名空间中。
问题:
来自 (1) 的 val 和来自 (2) 的键的类型是未知的。这是否意味着我不需要将函数放入任何命名空间,或者我是否需要将它们放在容器所属的 std 命名空间中?
是否有可能改进 (2) 编译器首选 (1) 对于 std::map、std::set、boost::unordered_map、boost::unordered_set?
boost::algorithm::contains()。我需要为我的包装器选择另一个名称吗?
(1) 不要向 std 命名空间添加任何内容
(2)正如Space_C0wb0y所指出的,(2)不是局部专业化,而是超载。我不确定这是否是标准行为,但在VS2008上,这个问题得到了正确解决(重载版本用于地图)。无论哪种情况,我认为一个稍微好一点的版本是:
template<typename C>
bool contains(const C & mapContainer, const typename C::key_type & key)
{
// std::map.find() is better than std::find used in (1)
return mapContainer.find(key) != mapContainer.end();
}
这是一个部分专用化(T 专用于 C::key_type),并且适用于所有具有 key_type typedef 的类型(例如 std::map、boost::unordered_map 等)。
(3)放入单独的命名空间(见@Tony的答案)
旁注:我不确定我是否认为这些函数应该具有相同的名称。如果我看到一个函数包含 maps() 接受一个 map + 另一个参数,我可以认为 (1) 该函数检查映射是否包含给定值的条目(例如,某个键具有提供的值)或 (2) 该函数检查映射中是否有这样的条目(例如,提供的值是一对)。相反,我会为地图调用函数 contains_key()。
编辑:经过一番检查,我怀疑上面的代码不合规,因为它使用了"模板类型定义"。这不是标准的C++功能,但似乎Visual Studio在某些情况下支持它。可能有一个解决方法,但我现在不够聪明,想不出一个解决方法。
在第 3 号上。 应将包含的版本放在其自己的命名空间中,以避免命名冲突。这就是命名空间的目的。
是的,将它们保存在单独的命名空间中。
唯一要与参数类型放在同一命名空间中的是运算符重载,以允许 Koenig(依赖于参数)查找。这些不是重载运算符。故事结束。
请注意,这也回答了问题 2.:如何使编译器首选您的实现:
using myownversions::contains;
(假设您现在将命名空间命名为 myownversions
)
- 不得将它们放入
std
命名空间中。这是禁止的。您可以将它们放入您喜欢的任何命名空间中。 - 你可能在那里可以做一些SFINAE魔法,但我自己想不出。
- 看@Tony的回答。
- boost::bind()类似的东西,但用于函数调用
- 为什么通用参考概念不适用于函数指针的地图插入
- 为什么保守调整大小不适用于函数中的 Ref 变量?
- 用于C++函数的自动 C 包装器
- 函数指针类型不能用于函数原型
- 如何将"using"用于函数?
- 指针或局部变量,用于函数的输出参数
- C 类模板扣除(P0091R0)用于函数参数
- 用于函数签名的专用模板
- 为什么关键字“显式”不适用于函数参数
- 预期的"("用于函数式铸造或类型构造
- 将模板用于函数时出错
- 部分模板专用化可能不适用于函数,但重载不是一回事吗?
- if 语句不适用于函数
- 将数组用于函数输入参数
- 如何确定哪个 Windows DLL 用于函数调用
- 转换运算符不适用于函数参数
- 为什么参数相关查找不适用于函数模板dynamic_pointer_cast
- 用于函数样式强制转换或类型构造的预期 c++ Xcode '('
- c++14用于函数绑定的可变lambda捕获