[英]Adding methods with template specialization
我有一个称为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
。 我确信编译器甚至可以在编译时使用这种签名来计算哈希,这也将有助于加快处理速度。
有没有一种方法可以在C++11
做到而无需模板专门化整个Map类并重写所有方法?
您可以添加另一个重载valueFor(char const * key)
。 如果Key
不是std::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!
}
只是削弱您的类型要求。 只要表达式hash<Key>(arg)
有效,您的valueFor
(无需)关心参数的类型。
因此,您可以将valueFor
其参数类型的模板,并仅对哈希函数和关键比较器(如有必要)进行专门化处理。
例如。 (未经测试,为简洁起见,使用C ++ 17 string_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));
// ...
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.