将const rvalue绑定到右值引用

时间:2014-09-13 06:54:01

标签: c++ c++11 smart-pointers pass-by-rvalue-reference

在实现BS树的过程中,我注意到自从我开始使用C ++ 11智能指针以来我不太确定的事情,这让我想知道为什么会这样。如果我使用 init-brace pairs {} 而不是括号,下面的代码工作正常;我的个人规则是为每个成员(直接或通过ctor)初始化值,因为 Node :: right Node :: left 都是因此,智能指针是 nullptr 问题1 :为什么括号失败并且init-brace对成功?在这种情况下,两者之间是否存在语义差异?

BST 中,在采用std :: initializer_list的ctor中,据我所知,std :: initializer_list元素只能复制,根据this。因此,如果我没有错,根据Scott Meyer在最近的GN13中,对const对象执行移动只会触发对象的复制。

Quesion 2 为什么编译器在调用 BST :: insert(T&&)时无法复制对象?

#include <memory>

template<typename T>
struct Node
{

    //~ std::unique_ptr<Node<T>> left ( nullptr ), right ( nullptr );
    std::unique_ptr<Node<T>> left { nullptr }, right { nullptr };
    Node<T> *parent = nullptr;
    T value { };
    Node<T> () = default;
    Node<T> ( T && val, Node<T> * _left = nullptr, Node<T> *_right = nullptr,
          Node<T> *_parent = nullptr ): left( _left ), right ( _right ), parent( _parent ),
                                        value ( std::move( val ) )
        {

        }
};
template<typename T>
struct BinarySearchTree
{
    std::unique_ptr<Node<T>> root;

    BinarySearchTree(): root { nullptr } { }
    BinarySearchTree( std::initializer_list<T> && lst ): BinarySearchTree { }{
    //If the below code were changed to
    //~ for( auto && i: lst ){ it would be an error
        for( typename std::remove_reference<typename std::remove_const<T>::type>::type i: lst ){
            this->insert( std::move( i ) );
        }
    }
    void insert( T && v ) { }
};

int main(){
    BinarySearchTree<int> a { 11, 24 };

    return 0;
}

1 个答案:

答案 0 :(得分:3)

  

为什么括号失败并且init-brace对成功?

因为括号用于函数声明。您不能使用它们来初始化类范围内的变量。即使int i(1);也无法工作。

  

为什么编译器在调用BST :: insert(T&amp;&amp;)时无法复制对象?

你在比较中不公平。在auto版本中,您明确要求引用类型。在非auto版本中,您明确要求使用非引用类型。删除&&会使auto版本也正常工作。

您的insert方法需要T &&。这是一个非const限定的引用,因此无法绑定到任何const对象。

auto &&推断为const int &&,因为您无法更改initializer_list<int>的内容:其begin()end()方法返回const int * 。添加std::move无法正常工作,您无法绕过const

auto会推断为int,并会有效:您将获得一个新的非const int局部变量i,其中包含初始化列表中的值的副本。您可以对该局部变量形成非const引用。