0

I'm trying to write a hash table demo. By using chain to solve hash collision. I want to write some code like below(pseudo code) that to check if the class put in hash table implement operator<. If the class key_type implements operator<, I can use red-black tree to contain the data, otherwise I can only use linked list.

#ifimplement operator<
    typedef map<key_type, value_type> bucket_type;
#else
    typedef list<pair<key_type, value_type> > bucket_type;
#endif
wangjianyu
  • 97
  • 4
  • Related: [Detect implementation of conversion operator](https://stackoverflow.com/questions/51172669/), [Any way to determine if class implements operator()](https://stackoverflow.com/questions/3077850/) – Remy Lebeau Apr 24 '23 at 00:07

2 Answers2

0

Use expression SFINAE to detect whether using operator< would work.

#include <list>
#include <map>
#include <utility>

template <typename K, typename V, typename = void>
struct MyContainerT : std::false_type {
  using bucket_type = std::list<std::pair<K, V>>;
};

template <typename K, typename V>
struct MyContainerT<K, V, decltype(void(K{} < K{}))> : std::true_type {
  using bucket_type = std::map<K, V>;
};

template <typename K, typename V>
using MyContainer = typename MyContainerT<K, V>::bucket_type;

class C {};

int main() {
  MyContainer<int, int> c1;
  MyContainer<C, int> c2;
  c1[1] = 1;
  c2.push_back(std::make_pair(C{}, 1));
}

https://godbolt.org/z/53svG3be6

273K
  • 29,503
  • 10
  • 41
  • 64
0

The answer will be different for different c++ versions. You can probably write:

template<typename key_value, typename value_type, typename /* omitted */ = decltype(std::declval<key_value>() < std::declval<key_value>())>
std::map<key_value, value_type>  supports_less_than_test(const key_value&);
template<typename key_type, typename value_type>
std::list<std::pair<key_type, value_type>> supports_less_than_test(...);

template<typename K, typename V>
struct get_type {
    using value = decltype(supports_less_than_test<K, V>());
};

template<typename K, typename V>
using get_type_t = get_type<K, V>;
Egor
  • 1
  • 1