进一步重新值引用和临时对象
Further rvalue references and temporary objects
在详细阐述我之前的问题时,我想了解这个真实场景中发生了什么。我有以下模板功能:
template <typename Key, typename Value, typename HashFunction, typename Equals>
void FastHash<Key, Value, HashFunction, Equals>::Insert(const Key& key, const Value& value)
{
Insert(std::make_pair(key, value));
}
例如,用左值和右值的混合调用,比如这个调用:
std::string name = "The Great";
hashTable.Insert(name, "Gatsby");
(用于测试目的)。上面的Insert
调用
template <typename Key, typename Value, typename HashFunction, typename Equals>
void FastHash<Key, Value, HashFunction, Equals>::Insert(pair<const Key, Value>&& keyValuePair)
{
if (buckets.size() == 0)
{
buckets.resize(1);
}
HashFunction hash;
unsigned long hashValue = hash(keyValuePair.first) % buckets.size();
buckets[hashValue].push_back(std::move(keyValuePair));
}
几个问题:
1。由于通过引用传递,我希望生成一对(其中一个元素是文字字符串)是未定义的行为。是这样吗?
2.当我进入make_pair
行时,代码首先调用make_pair(_Ty1&& _Val1, _Ty2&& _Val2)
,因此编译器似乎将key
和value
解释为右值。为什么?
3。进入第二个Insert
方法之前的下一个调用是pair(pair<_Other1, _Other2>&& _Right)
。无论第二CCD_ 8采用CCD_ 9还是CCD_。这是怎么回事?
4.最后一个,第二个Insert
应该取const pair&
还是pair&&
,考虑到它的作用?
更新:在观看了Scott Meyer关于通用参考文献的精彩视频后,阅读了模板推导和参考文献折叠规则,在您的帮助下,我可以回答1、2和4。但我仍然无法理解为什么pair
的move构造函数在Insert
调用之前被调用。有什么帮助吗?
进入第二个Insert方法之前的下一个调用是
pair(pair<_Other1, _Other2>&& _Right)
。无论第二个插入采用&&
还是const &
,都会发生这种情况。这是怎么回事?
这就是std::pair
的转换构造函数:它将您传递的对std::make_pair(key, value)
-从std::pair<Key, Value>
转换为第二个Insert
函数的参数类型std::pair<const Key, Value>
。如果您自己指定对类型,而不是让std::make_pair
推导它,则可以避免转换:
Insert(std::pair<const Key, Value>{key, value});
当然,这是将参数复制到pair
中,在C++11中,我们有一条经验法则,即如果要复制某个东西,则应按值接受它。因此,也许可以将这个Insert
实现为:
template <typename Key, typename Value, typename HashFunction, typename Equals>
void FastHash<Key, Value, HashFunction, Equals>::Insert(Key key, Value value)
{
Insert(std::pair<const Key, Value>{std::move(key), std::move(value)});
}
- 为什么当我们有常量引用时创建临时对象?
- 返回对临时对象的引用
- 通过引用传递临时对象
- 存储对(可能)临时对象的引用是否合法,只要引用不比对象存活?
- 对临时对象的Const引用不会延长其生存期
- 为什么引用类型在使用临时对象访问时是左值
- 取消引用临时对象上的运算符
- 常量引用函数参数:是否可以禁止临时对象?
- 为什么临时对象可以绑定到常量引用?
- 为什么常量引用不能延长通过函数传递的临时对象的生存期?
- 使用常量引用延长临时对象的寿命
- 从函数返回引用是否会导致在使用'auto'时创建新的临时对象?
- 关于将临时对象传递给常量引用
- 将临时对象绑定到常量引用
- C++17:是编译器为(静态存储持续时间)const引用绑定创建的可修改的临时对象(和存储)
- 返回对本地临时对象 C++ 的引用
- 模板类型推导警告返回对本地临时对象的引用
- 为什么不对临时对象进行非常量引用
- 堆上是否会分配内存以支持临时对象到常量引用的嵌套绑定
- 传递给存储常量引用的成员的临时对象的生存期