简体   繁体   English

进一步的右值引用和临时对象

[英]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) ,因此编译器似乎正在将keyvalue解释为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 a const & . 无论第二个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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM