[英]Further rvalue references and temporary objects
In elaboration of my previous question and question , I'd like to understand what goes on in this real scenario. 在详细阐述我之前的问题和疑问时 ,我想了解这个真实场景中发生了什么。 I have the following template function:
我有以下模板功能:
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));
}
called with, for instance, a mixture of lvalues and rvalues, like in this call: 例如,使用左值和右值的混合调用,就像在这个调用中一样:
std::string name = "The Great";
hashTable.Insert(name, "Gatsby");
(for testing purposes). (用于测试目的)。
Insert
above calls 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));
}
A few questions: 几个问题:
1. I would expect making a pair one of whose elements is a literal string to be undefined behaviour, owing to passing by reference. 1.由于通过引用传递,我期望将其元素之一的字符串作为未定义行为的文字字符串。 Is that so?
是这样吗?
2. When I step into the make_pair
line, the code first calls make_pair(_Ty1&& _Val1, _Ty2&& _Val2)
, so it seems that the compiler is interpreting key
and value
as rvalues. 2.当我进入
make_pair
行时,代码首先调用make_pair(_Ty1&& _Val1, _Ty2&& _Val2)
,因此编译器似乎正在将key
和value
解释为rvalues。 Why? 为什么?
3. The next call before going into the second Insert
method is pair(pair<_Other1, _Other2>&& _Right)
. 3.进入第二个
Insert
方法之前的下一个调用是pair(pair<_Other1, _Other2>&& _Right)
。 This happens irrespective of whether the second Insert
takes an &&
or a const &
. 无论第二个
Insert
是否采用&&
或const &
都会发生这种情况。 What's going on here? 这里发生了什么?
4. Tied to this last, should the second Insert
take a const pair&
or a pair&&
, given what it does? 4.绑到最后,如果第二个
Insert
取一个const pair&
或一pair&&
,它的作用是什么?
Update: After watching Scott Meyer's excellent video on universal references, reading on template deduction and reference collapsing rules, and with your help I can answer 1, 2, and 4. But I still cannot understand why the pair
's move constructor is called just before the Insert
call. 更新:观看Scott Meyer关于通用引用的优秀视频,阅读模板演绎和参考折叠规则,并在您的帮助下我可以回答1,2和4.但我仍然无法理解为什么
pair
的移动构造函数被称为在Insert
调用之前。 Any help on that? 对此有何帮助?
The next call before going into the second Insert method is
pair(pair<_Other1, _Other2>&& _Right)
.进入第二个Insert方法之前的下一个调用是
pair(pair<_Other1, _Other2>&& _Right)
。 This happens irrespective of whether the second Insert takes an&&
or aconst &
.无论第二个Insert是否采用
&&
或const &
都会发生这种情况。 What's going on here?这里发生了什么?
That is std::pair
's converting constructor: it's converting the pair that you pass - std::make_pair(key, value)
- from std::pair<Key, Value>
to the second Insert
functions's parameter type std::pair<const Key, Value>
. 那是
std::pair
的转换构造函数:它将你传递的对 - std::make_pair(key, value)
- 从std::pair<Key, Value>
转换为第二个Insert
函数的参数类型std::pair<const Key, Value>
。 You could avoid the conversion if you specify the pair type yourself instead of having std::make_pair
deduce it: 如果您自己指定对类型而不是使用
std::make_pair
推导它,则可以避免转换:
Insert(std::pair<const Key, Value>{key, value});
Of course, this is copying the parameters into a pair
, and in C++11 we have the rule of thumb that if you are going to copy something you should accept it by value. 当然,这是将参数复制成一
pair
,而在C ++ 11中我们有经验法则,如果要复制某些东西,你应该按值接受它。 So maybe implement this Insert
as: 所以也许实现这个
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)});
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.