2014-09-13 62 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引用。

相關問題