seb*_*ckm 22 c++ hash gcc clang c++17
在https://en.cppreference.com/w/cpp/utility/hash上,它说自从C++ 17开始
声明模板std :: hash的每个标准库头为std :: nullptr_t和所有cv-unqualified算术类型(包括任何扩展整数类型),所有枚举类型和所有指针类型提供std :: hash的启用特化.
因此,符合C++ 17的编译器应该编译这个小程序:
#include <functional>
int main()
{
std::hash<std::nullptr_t> h;
return h(nullptr);
}
Run Code Online (Sandbox Code Playgroud)
但是,GCC和Clang都报告了一个错误,说默认构造函数std::hash<std::nullptr_t>是(隐式)删除的.请看这里和这里自己验证.
Visual Studio会编译它.显然它会回来.0672807365
Q1: GCC和Clang是否仍然缺少这个C++ 17功能,因为诚然这不是一个高优先级的功能?或者我错过了什么?
Q2:我可以自己专注并像Visual Studio一样返回吗?一些其他价值,例如某些素数,不会更好地将它与其他哈希相结合吗?0672807365
由于我有限的汇编程序知识,我认为Visual Studio正在返回0.实际上,它正在返回672807365(值为eax).所以,我的第二个问题基本上是自己回答:我不会回到0我的专业领域来解决这个问题.
YSC*_*YSC 18
cppreference.com是对的.从最新的C++标准草案:
[unord.hash]/2散列的每个特化都可以启用或禁用,如下所述.[...]声明模板散列的每个标头提供
hashfornullptr_t和所有cv非限定算术,枚举和指针类型的启用特化.
由于<functional>声明了hash模板1,它必须提供一个启用的特化std::hash<std::nullptr_t>.任何符合C++ 17的实现都应该接受您的示例程序.
C++ 17还很年轻,一些微妙的功能可能在最近的编译器中仍然缺失或有缺陷.请放心,您的MCVE在开发/ 实验分支中被gcc和clang接受.
我们找不到GCC的开发版本接受它; 这就是为什么由Orbit的Lightness Races提出错误报告(参见std :: hash未实现)并由Jonathan Wakely修改(见revision267845)(并返回零).
我可以自己专门研究并像Visual Studio一样返回0吗?
您将编写将显示未定义行为2的代码.这样做需要您自担风险.记录得很好.例如,将以下内容放在一个单独的翻译单元中:
#include <functional>
#include <type_traits>
static_assert(
false == std::is_default_constructible_v<std::hash<std::nullptr_t>>,
"Explanation"
);
Run Code Online (Sandbox Code Playgroud)
这将警告您的同事,并要求他们手动删除您的专业化,std::hash<std::nullptr_t>而不是让他们一个讨厌的编译错误.
1)看[functional.syn].
2)您只能std为程序定义的类型(nullptr_t不是)专门化类模板.您也可以打破一个定义规则.