用于创建未命名实例的语法

Grammar to make unnamed instance

本文关键字:语法 实例 未命名 创建 用于      更新时间:2023-10-16

我正在为pair < int,int >键制作哈希函数。

无论如何,我找到了以下使用std::hash<>的实现:

typedef struct hasher_t {
template <class T1, class T2>
size_t operator()(const pair<T1,T2>& key) const {
//standard hasher for T1, T2

auto h1 = std::hash<T1>()(key.first);   //also possible
auto h2 = std::hash<T2>()(key.second); //also possible

/*
auto h1 = std::hash<T1>{}(key.first);
auto h2 = std::hash<T2>{}(key.second);
*/
return h1 ^ (h2 - 1);
}
} hasher;

std::hash<T1>()std::hash<T1>{}都有效,但我不知道为什么会这样。

我什至找不到这方面的参考文章。

我猜他们俩都为类std::hash<T1>做了字面上的"未命名的时间实例",并调用operator()(T1)方法。对吗?

是的,两者都构造临时std::hash,然后在临时对象上调用operator()

std::hash<T1>()执行值初始化,

1,5( 当使用由一对空括号组成的初始值设定项创建无名临时对象时or braces (since C++11);

临时由默认构造函数初始化。

std::hash<T1>{}执行列表初始化(自 C++11 起(,

2( 使用大括号初始化列表初始化未命名的临时

作为效果,临时也由默认构造函数进行值初始化。

std::hash<T>是一个类型而不是一个函数。您可以将其视为函子。所以你必须创建一个实例。

回答你的问题,是的,两种方式都创建一个std::hash<T>对象,并调用()运算符对其进行初始化。

std::hash<T1>()使用括号进行初始化。它也称为值初始化

std::hash<T1>{}是使用大括号进行初始化。auto h1 = std::hash<T1>{}(key.first);发生的情况是{}创建一个std::hash<T1>实例,然后在您的实例上(key.first)调用运算符()。这也称为聚合初始化或列表初始化。

在 C++11 及更高版本中,您可以使用 std::hash{}(即大括号 而不是括号(来构建对象。