添加具有模板专用化的方法

Adding methods with template specialization

本文关键字:方法 专用 添加      更新时间:2023-10-16

我有一个名为 Map 的哈希表容器,方法如下:

Value Map<Key, Value>::valueFor(const Key& key);

不幸的是,最常用的情况是Key = std::string我们通常使用字符串文字调用该方法,例如:

const Value v = map.valueFor("my_key");

我们失去了一些循环来创建std::string。因此,我想添加一个重载

Value Map<std::string, Value>::valueFor(const char* key);

Key = std::string.我相信编译器甚至可以在编译时使用这样的签名计算哈希,这也将有助于加快速度。

有没有办法在没有专门化整个 Map 类的模板并重写所有方法的情况下C++11做到这一点?

您可以添加另一个重载valueFor(char const * key)。 如果Keystd::string,您可能还想使用 SFINAE 禁用此重载。

#include <iostream>
#include <string>
#include <type_traits>
template < typename Key, typename Value >
struct Map
{
Value valueFor(Key const& key)
{
std::cout << "valueFor(const Key& key)n";
return Value{};
}
template < typename _Key = Key,
typename = typename std::enable_if< std::is_same < _Key, std::string >::value >::type >
Value valueFor(char const * key)
{
std::cout << "valueFor(char const * key)n";
return Value{};
}
};
int main()
{
Map<std::string, int> map;
int v = map.valueFor("my_key");
Map<int, int> other_map;
//int v = other_map.valueFor("my_key"); // BOOM!
}

只是削弱了你的类型要求。你的valueFor不关心参数是什么类型,只要表达式hash<Key>(arg)有效。

因此,您可以模板valueFor其参数类型,并专门化哈希函数,并在必要时专门设置密钥比较器。

例如。(未经测试,为简洁起见,使用 C++17string_view(

template <typename K>
struct Hasher
{
static size_t hash(K const &k) { return std::hash<K>()(k); }
};
template <>
struct Hasher<std::string>
{
static size_t hash(std::string const &s) {
return std::hash<std::string>()(s);
}
static size_t hash(std::string_view const &sv) {
return std::hash<std::string_view>()(sv);
}
static size_t hash(const char *cstr) {
return std::hash<std::string_view>()({cstr});
}
};
template <typename Key, typename Value>
template <typename KeyArg>
Value Map<Key,Value>::valueFor(KeyArg&& arg)
{
auto hash = Hasher<Key>::hash(std::forward<KeyArg>(arg));
// ...
}