首页 > 解决方案 > 如何为序列和关联容器实现通用功能?

问题描述

我正在考虑编写一个适用于序列和关联容器的函数。这就像

 template<class C, class V = typename C::key_type>
 bool has_val(const C& c, const V& v)`

在函数内部,我想

  1. 检查类 C 是否具有const_iterator find(key_type) const容器类的成员函数,如 set/map。
  2. 如果它不包含 find(),那么我们std::find()使用std::vector.

检查的最佳做法是什么,(1)?

如果我上面描述的不是最好的,请告知是否有更好的方法?

(不幸的是,我无法使用宏访问较新的 Folly,FOLLY_create_member_invoker但我确实有FOLLY_CREATE_HAS_MEMBER_FN_TRAITS。不过,我无法成功通过)

标签: c++templatesc++17c++-standard-libraryfunction-templates

解决方案


使用 SFINAE 检测是否使用c.find()

#include <algorithm>

template <class C, class V, typename = void>
constexpr inline bool use_mem_find = false;

template <class C, class V>
constexpr inline bool use_mem_find<C, V,
  std::void_t<decltype(std::declval<const C&>().find(std::declval<const V&>()))>> = true;

template<class C, class V> 
bool has_val(const C& c, const V& v) {
  auto end = std::end(c);
  if constexpr (use_mem_find<C, V>)
    return c.find(v) != end;
  else
    return std::find(std::begin(c), end, v) != end;
}

演示。


推荐阅读