gpt4 book ai didi

c++ - 用户类型的 hash 仿函数属于哪个命名空间?

转载 作者:可可西里 更新时间:2023-11-01 15:24:27 24 4
gpt4 key购买 nike

我不清楚 C++11 标准中用户定义的 hash<T>应定义仿函数。

例如,在 23.5.2 Header <unordered_map> ,它显示:

template <class Key,
class T,
class Hash = hash<Key>,
class Pred = std::equal_to<Key>,
class Alloc = std::allocator<std::pair<const Key, T> > >
class unordered_map;

这表明,默认情况下,hash<T>在全局命名空间中搜索,而 equal_to<>std 中搜索命名空间。

为什么 hash<> 之间的命名空间不同?和 equal_to<>

(实际上,在 http://www.cplusplus.com/reference/unordered_map/unordered_map/ 的描述中,都没有指定 std 命名空间。)

因此,在定义 hash<> 时用户类型的仿函数,我们应该将它包含在 namespace std { } 中吗? block ,还是可以保留在当前命名空间中?

如果代码没有 using namespace std; , STL 容器如何像 unordered_map知道看std预定义的命名空间 hash<>与原始类型相关的仿函数?好像是默认的Hash = hash<Key>将找不到这些。

抱歉,如果这些是愚蠢的问题..

最佳答案

首先,模板没有“参数依赖查找”。所以hash<Key>将始终引用相同的模板,无论是在 std 中或在全局命名空间中,独立于 Key .如果它已解析为不同翻译单元中的不同模板,则会因 ODR 违规而导致未定义的行为。仅此一项就表明 hash这里的意思是std::hash , 就好像 unordered_map声明如下:

namespace std {
template<class T> struct hash;

template <class Key,
class T,
class Hash = hash<Key>, // resolves to std::hash<Key> for all Keys
class Pred = std::equal_to<Key>,
class Alloc = std::allocator<std::pair<const Key, T> > >
class unordered_map;
}

但是,标准头文件中声明的类型不需要在源代码中编写(原则上它们可以内置于编译器或由其他一些魔术预编译)。该标准要求每个标准 header 仅在其概要中声明类型,这意味着通过省略 std::hash声明该标准允许一些假设的实现以避免上述 namespace 污染。这就解释了为什么您在概要中看不到上述声明。

为了进一步支持上述结论,我们转到§20.8.12 类模板哈希 [unord.hash],内容如下:

The unordered associative containers defined in 23.5 use specializations of the class template hash as the default hash function.

这一段是指std::hash ,我们可以从 <functional> 的概要中推断出这一点.

底线:这是标准格式中的不一致之处。有很多不一致之处,所以这个具体案例一点也不奇怪。在这种情况下,人们必须通过推断什么是唯一明智的事情来理解意图。

专门化。您在模板声明的命名空间中专门化模板。您被明确授予为您自己的类型专门化标准模板的权利:

namespace std {
template<> struct hash<YourClass> {
// specialization goes here
};
}

关于c++ - 用户类型的 hash<T> 仿函数属于哪个命名空间?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14669995/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com