我编写了简单的泛型函数来检查任何STL容器是否有一个元素。好像挺好的。我已经用VC++,GCC和Clang编译器测试了它。它工作得很完美。
我怎样才能进一步改进。
#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";
}发布于 2016-06-17 08:58:33
不错的玩具!我花了一段时间才意识到这件事。看上去没问题。我唯一想到的就是为什么不使用std::enable_if,因为它要简单得多。
#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()
{
/* */
}https://codereview.stackexchange.com/questions/132253
复制相似问题