制作一般的容器搜索功能

时间:2014-12-22 23:22:25

标签: c++ dictionary stl containers

我希望能够使用函数搜索任何标准容器。例如,如果我有std::vectorstd::map,我想知道它是否包含某个元素。

我一直在使用这段代码:

template<typename T, typename valueType>
bool contains(T vec, valueType element) {
    return std::find(vec.begin(), vec.end(), element) != vec.end();
}

它在std::map上不起作用,如果我将函数传递给地图,它就不会编译,这是我想要它做的事情。我能以任何方式做到这一点吗?

1 个答案:

答案 0 :(得分:0)

根据您的评论,您应该有两个版本的contains()功能:

  1. 在第一个参数上利用find()成员,将第二个参数的对象作为参数。这样,就会使用由关联容器提供的O(log n)O(1)(预期)版本的find()
  2. 一个后退版本,对序列进行线性搜索。
  3. 可能需要编译器确定要使用的版本。结果代码看起来像这样:

    struct container_find {
        template <typename C, typename K>
        static std::true_type test(decltype(std::declval<C const&>().find(std::declval<K const&>()))*);
        template <typename C, typename K>
        static std::false_type test(...);
    };
    
    template <typename C, typename K>
    typename std::enable_if<!decltype(container_find::test<C, K>(0))::value, bool>::type
    contains(C const& c, K const& k) {
        return c.end() != std::find(c.begin(), c.end(), k); 
    }
    
    template <typename C, typename K>
    typename std::enable_if<decltype(container_find::test<C, K>(0))::value, bool>::type
    contains(C const& c, K const& k) {
        return c.end() != c.find(k);
    }
    

    container_find只是一个帮助器,用于检测容器类型是否提供find()的可用版本。结果与std::enable_if<...>一起使用以启用contains()的相应版本。 contains()的实现也避免了复制容器。