2014-09-13 39 views
0

在实现BS树时,我注意到一些自从我开始使用C++ 11智能指针后不太确定的事情,这让我很奇怪为什么会这样。下面的代码工作正常,如果我使用init-brace对{}而不是括号;我个人规则是看重初始化每个成员(直接或通过构造函数),并自节点::右节点::留下都是智能指针,因此,nullptr它。 问题1:为什么括号失败并且init-brace对成功?仅在这种情况下,两者之间是否有语义上的区别?将常量左值与右值引用绑定

BST,在带有std的构造函数:: initializer_list,我明白的std :: initializer_list元素仅能够复制,根据this。所以如果我没有错的话,根据最近GN13的Scott Meyer的说法,对const对象进行移动只会触发对象的copy-ctor。

Quesion 2为什么编译失败对象在通话复制到BST ::插入(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; 
} 

回答

3

为什么括号失败和init-括号对成功吗?

由于括号用于函数声明。你不能用它们在类作用域初始化变量。即使int i(1);也不起作用。

为什么编译器不能在物体的调用BST ::插入(T & &)复制?

你在比较中不公平。在您的auto版本中,您明确要求参考类型。在您的非auto版本中,您明确要求提供非参考类型。删除&&将使auto版本也工作。您的insert方法需要T &&。这是非const限定参考,因此它不能绑定到任何const对象。

auto &&被推断为const int &&,因为你不能改变initializer_list<int>的内容:其begin()end()方法返回const int *。添加std::move不起作用,你不能绕过const那样。

auto会推断到int,而将工作:你会得到一个新的非constint局部变量i,含值的副本在初始化器列表。您可以形成对该局部变量的非const引用。

相关问题