用const T&和T &&这两种类型的参数实现函数

时间:2019-07-26 12:54:52

标签: c++ c++17

我正在通过与std :: set兼容的接口来实现某些特定的BST的卑微尝试,而尝试次数越多,我遇到的问题就越多。

例如,问题之一是在实现insert方法的两个重载版本时如何最小化代码重复:

std::pair<iterator, bool> insert(const value_type & value)

std::pair<iterator,bool> insert(value_type&& value);

当前,我实现了第一个重载,该重载在内部调用了私有方法FindNodeByKey:

template<class T, class Compare = std::less<>, class Allocator = std::allocator<T>> 
class my_set
{
   ...

private:

    template <class Key>
    Node * FindNodeByKey(const Key & key) const
    {
        Node * x = m_root;

        //walk down the tree
        while (x != nullptr)
        {
            if (m_comp(key, x->value))
            {
                x = x->left;
            }
            else if (m_comp(x->value, key))
            {
                x = x->right;
            }
            else
            {
                return x;
            }
        }

        return nullptr;
    }

    Comparer m_comp;
}

其中m_comp是Comparer实例,Node是包含BST链接和类型T的值的结构,KeyComparer支持的任何类型,特别是value_type

1)用类型为FindNodeByKey的参数实现Key &&的最佳方法是什么(与第二个insert重载一起使用)?有没有办法避免其代码重复?

2)我应该将Key &&传递给比较器吗?

3)老实说,我不太理解为什么我使用std::less<>,但是std :: set使用std::less<T>作为默认比较器。

EDIT1:

value_type不能保证具有复制构造函数(可复制)。

3 个答案:

答案 0 :(得分:3)

您只需将两个重载都转发到实现模板:

Promise<Promise<any>[]>

答案 1 :(得分:1)

您绝对不应出现Node * FindNodeByKey(Key&& key) const重载。这没有意义,因为您没有使用参数key进行复制。您只是在使用它来将它(多次)传递给m_comp(后者又不会复制它)。

当函数需要制作const T& x的一个且仅一个副本时,通常希望T&& xx重载。然后,在传递的值是临时值的情况下,可以对此进行优化,而不是执行复制操作。

对于插入,是的,在这里您可以实现两个重载,因为insert非常适合上述类别。并且两个重载都应调用FindNodeByKey(const Key&)

答案 2 :(得分:0)

您可以通过简单地从另一个重载中调用来消除必须实现的一个重载:

std::pair<iterator, bool> insert(const value_type & value)
{
    return insert(value_type(value));
}

只要您的value_type具有复制构造函数,这将创建值的临时副本,然后调用带有右值引用的insert重载。