C++ 模板特化 - 将其他整数类型委托(delegate)给 uint64_t

标签 c++ templates template-specialization

我正在尝试为与 std::unordered_map 一起使用的整数类型实现自定义散列仿函数。为此,我想为无符号 64 位整数提供一个实现,并通过转换/扩展将所有其他实现委托(delegate)给该实现。

我过去通过为我想要的每个额外类型定义特化成功地做到了这一点:

template <typename T> struct custom_hash { size_t operator()(const T&) const };
template <> struct custom_hash<uint64_t> { size_t operator()(uint64_t x) const { /* ... */ }};
template <> struct custom_hash<int> { custom_hash<uint64_t> h; size_t operator()(int x) const { return h(x); }};
/* ... */

但我想知道如何在不对每个其他类型进行专门化的情况下执行此操作。

我试过了 something I read on SO使用 std::enable_ifstd::is_integral:

template <typename T> struct custom_hash { /* ... */ };
template <> struct custom_hash<uint64_t> { /* ... */ };

template <typename Int, typename = typename enable_if<is_integral<Int>::value, Int>::type>
struct custom_hash<Int> {
    custom_hash<uint64_t> h;

    size_t operator()(Int x) const {
        return h(x);
    }
};

但这没有用。 Clang 提示

error: default template argument in a class template partial specialization

error: too many template parameters in template redeclaration

我认为发生这种情况是因为声明与之前没有定义的声明发生冲突。我对模板了解不够,无法解决这个问题。

最佳答案

问题是模板特化的所有模板参数都必须从基本模板中推导出来,而不是从彼此推导出来。

如果你可以在基础模板中添加一个虚拟参数,或者在你控制的基础中进行特化,那么你就是黄金:

template <typename T, class = void>
struct custom_hash;
template <>
struct custom_hash<uint64_t>
{ size_t operator()(uint64_t x) const { /* ... */ }};
template <class T>
struct custom_hash<T, std::enable_if_t<std::is_integral<T>() && sizeof(T) <= sizeof(uint64_t)>
{ size_t operator()(int x) const {  custom_hash<uint64_t> h; return h(uint64_t(x)); }};

关于C++ 模板特化 - 将其他整数类型委托(delegate)给 uint64_t,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57452127/

相关文章:

c++ - C++ 中的枚举器有自动名称查找吗?

java - java中如何获取uint32_t对应的唯一值?

c++ - 如何检查功能模板是否已专门化?

c++ - VS2015无法从 'initializer list'转换为 'std::string'错误

c++ - 使用 CFDictionarySetValue() 将结构存储为值

c++ - 具有模板化继承的纯虚函数

ruby - 添加对渲染 View 到仅限 Rails api 的应用程序的支持

c++ - 函数声明中箭头语法的优点

c++ - C++ 11 中具有多个模板参数的模板函数的特化

c++ - 使用模板参数作为模板参数