Я не уверен, что ужасно интересно указывать разные типы T_Key и T_Value для ваших классов hash и rehash. Если бы я решил эту проблему, я бы сначала попытался установить политику для ключа / val. Я склонен сказать, что, возможно, должен быть ValuePolicy вместо того, чтобы группировать его с KeyPolicy, но это ни здесь, ни там.
namespace hash {
namespace detail {
template<
typename Key
, typename Value
, typename KeyGetter
, typename KeyComparator>
class KeyPolicy {
public:
typedef Key key_t;
typedef Value value_t;
typedef KeyGetter get_t;
typedef KeyComparator compare_t;
};
}} // hash detail
HashTable
недействителен, если у него нет той же KeyPolicy, что и для повторной, и т. Д., Поэтому не указывайте его.
namespace hash {
namespace detail {
template<typename RehashPolicy>
class HashTableImpl {
public:
typedef RehashPolicy rehash_p;
typedef typename rehash_p::key_policy_t::key_t key_t;
// typedef ...
};
// this doesn't have a specific name, its anything.
template<typename KeyPolicy>
class SomeRehashPolicy {
public:
typedef KeyPolicy key_policy_t;
};
}} // hash detail
Вы можете добавить туда любые определения типов, которые вам нужны. Если бы я был приверженцем обзора кода, я бы, вероятно, попросил, чтобы такие вещи, как rehash_p
и key_policy_t
, были конфиденциальными. Это детали реализации, правда. Фактический инвариант, который вы пытаетесь защитить, это то, что находится в key_t
и т. Д.
Может быть, я за пределами разумных границ этикета, но мое честное мнение состоит в том, что вся эта конфигурация интересна только парню, который ее написал. Ни ты, ни кто-либо, кто использует это. Так что я бы раскрыл только одну или две конфигурации HashTable, которые люди на самом деле собираются использовать.
namespace hash {
struct stub {}; // sorry, I'm lazy
template<typename Key, typename Value>
class HashTable {
private:
typedef typename detail::KeyPolicy<Key, Value, stub, stub> key_p;
typedef typename detail::SomeRehashPolicy<key_p> rehash_p;
typedef typename detail::HashTableImpl<rehash_p> impl_t;
public:
typedef typename impl_t::key_t key_t;
};
} // hash
int main(int argc, char ** argv) {
hash::HashTable<int, double> hash_table;
return 0;
}
Многие детали явно не заполнены, но вы поняли.