【发布时间】:2013-12-15 11:06:34
【问题描述】:
在详细说明我之前的question 和question 时,我想了解在这个真实场景中发生了什么。我有以下模板函数:
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)。无论第二个Insert 采用&& 还是const &,都会发生这种情况。这里发生了什么?
4. 与最后一个相关联,考虑到它的作用,第二个 Insert 应该采用 const pair& 还是 pair&&?
更新:看了Scott Meyer关于通用引用的优秀视频,阅读了模板推导和引用折叠规则,在你的帮助下我可以回答1、2和4。但我还是看不懂为什么在Insert 调用之前调用pair 的移动构造函数。有什么帮助吗?
【问题讨论】:
-
hashTable的类型是什么? -
一个 FastHash
。我猜散列类型和相等类型并不重要。 -
字符串文字具有静态存储持续时间。
-
_Ty1&&是所谓的通用参考。在这种模式_Ty&&中,_Ty1可以推导出为左值引用(通过特殊规则,如果参数是左值)。如果推断它是对some_type的左值引用,则应用引用折叠并将some_type& &&折叠为some_type&- 参数变为左值引用。
标签: c++ c++11 undefined-behavior move-semantics rvalue-reference