首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >简单Contains()函数

简单Contains()函数
EN

Code Review用户
提问于 2016-06-17 03:08:27
回答 1查看 97关注 0票数 2

我编写了简单的泛型函数来检查任何STL容器是否有一个元素。好像挺好的。我已经用VC++,GCC和Clang编译器测试了它。它工作得很完美。

我怎样才能进一步改进。

代码语言:javascript
复制
#include <iostream>
#include <algorithm>
#include <utility>
#include <map>
#include <set>
#include <vector>
#include <array>
#include <type_traits>

// Detect if container has C::find
template <typename C> decltype(std::declval<C>().find(0), std::true_type{}) test(int);
template <typename C> std::false_type test(...);
template <typename C> using has_find = decltype(test<C>(0));

// Based on std::conditional
template <bool B, typename T, typename F>
struct conditional_impl
{
    constexpr static F pick(T&& , F&& f)
    {
        return std::forward<F>(f);
    }
};

template <typename T, typename F>
struct conditional_impl<true, T, F>
{
    constexpr static T pick(T&& t, F&&)
    {
        return std::forward<T>(t);
    }
};

template <bool B, typename T, typename F>
auto conditional(T&& t, F&& f)
{
    return conditional_impl<B,T,F>::pick(std::forward<T>(t), std::forward<F>(f));
}

// one for all and all for one
template <typename C, typename T>
auto contains(const C& container, const T& key)
{
    static auto first = [] (auto&& c, auto&& k)
    {
        return c.end() != c.find(k);
    };

    static auto second = [] (auto&& c, auto&& k)
    {
        return c.end() != std::find(c.begin(), c.end(), k);
    };

    auto op = conditional<has_find<C>::value>(first, second);

    return op(container, key);
}

int main()
{
    std::cout << std::boolalpha;

    std::array<int, 3> a = {{ 1, 2, 3 }};
    std::cout << contains(a, 0) << "\n";
    std::cout << contains(a, 1) << "\n\n";

    std::vector<int> v = { 1, 2, 3 };
    std::cout << contains(v, 0) << "\n";
    std::cout << contains(v, 1) << "\n\n";

    std::set<int> s = { 1, 2, 3 };
    std::cout << contains(s, 0) << "\n";
    std::cout << contains(s, 1) << "\n\n";

    std::map<int, int> m = { { 1, 1}, { 2, 2}, { 3, 3} };
    std::cout << contains(m, 0) << "\n";
    std::cout << contains(m, 1) << "\n";
}
EN

回答 1

Code Review用户

回答已采纳

发布于 2016-06-17 08:58:33

不错的玩具!我花了一段时间才意识到这件事。看上去没问题。我唯一想到的就是为什么不使用std::enable_if,因为它要简单得多。

代码语言:javascript
复制
#include <iostream>
#include <algorithm>
#include <utility>
#include <map>
#include <set>
#include <vector>
#include <array>
#include <type_traits>

// Detect if container has C::find
template <typename C> decltype(std::declval<C>().find(0), std::true_type{}) test(int);
template <typename C> std::false_type test(...);
template <typename C> using has_find = decltype(test<C>(0));

template <typename C, typename T>
typename std::enable_if<has_find<C>::value, bool>::type contains(const C& container, const T& key) {
    return c.end() != c.find(k);
}

template <typename C, typename T>
typename std::enable_if<!has_find<C>::value, bool>::type contains(const C& container, const T& key) {
    return c.end() != std::find(c.begin(), c.end(), k);
}

int main()
{
    /* */
}
票数 1
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/132253

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档