进一步重新值引用和临时对象

Further rvalue references and temporary objects

本文关键字:临时对象 引用 新值 进一步      更新时间:2023-10-16

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

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),因此编译器似乎将keyvalue解释为右值。为什么?

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)});
}