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

时间:2013-12-15 11:06:35

标签: c++ c++11 undefined-behavior move-semantics rvalue-reference

在详细阐述我之前的questionquestion时,我想了解这个真实场景中发生了什么。我有以下模板功能:

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));
}
例如,用pval和rvalues混合调用,就像在这个调用中一样:

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和{{ 1}}作为右值。为什么呢?

3。进入第二个value方法之前的下一个电话是Insert。无论第二个pair(pair<_Other1, _Other2>&& _Right)Insert还是&&,都会发生这种情况。这里发生了什么?

4。最后一次,如果第二个const &选择Insertconst pair&,它会做什么?

更新:观看了Scott Meyer关于通用参考的精彩视频,阅读模板演绎和参考折叠规则,并在您的帮助下我可以回答1,2和4.但我仍然无法理解为什么在pair&&调用之前调用pair的移动构造函数。对此有何帮助?

1 个答案:

答案 0 :(得分:1)

  

进入第二个Insert方法之前的下一个调用是pair(pair<_Other1, _Other2>&& _Right)。无论第二个插入内容是&&还是const &,都会发生这种情况。这是怎么回事?

这是std::pair转换构造函数:它将您传递的对 - std::make_pair(key, value) - 从std::pair<Key, Value>转换为第二个Insert函数的参数类型{{1} }。如果您自己指定对类型而不是std::pair<const Key, Value>推导出它,则可以避免转换:

std::make_pair

当然,这是将参数复制到Insert(std::pair<const Key, Value>{key, value}); ,而在C ++ 11中,我们有经验法则,如果要复制某些内容,则应按值接受它。因此,可以将此pair实现为:

Insert