2014-09-13 2 views
0

При внедрении дерева BS я заметил некоторые вещи, о которых я не был так уверен, так как начал использовать интеллектуальные указатели C++ 11, и это заставляет меня задаться вопросом, почему это так. Приведенный ниже код отлично работает, если я использую пары перпендикулярных {} вместо круглых скобок; мой личный правило является дорожить инициализировать каждый элемент (непосредственно или через CTOR) и так Node :: правой и Node :: осталось оба умные указатели, поэтому, nullptr это. Вопрос 1: Почему скобки не сработают, а пары инициации-прервать? В этом случае ТОЛЬКО есть ли какие-то смысловые различия между ними?Binding const rvalue to rvalue reference

В BST в CTOR, который принимает зЬй :: initializer_list, я понимаю, что СТД :: initializer_list элементы только копируемые, согласно this. Поэтому, если я не ошибаюсь, по словам Скотта Мейера в недавнем GN13, выполнение движения по объекту 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 -qualified ссылка, поэтому она не может привязываться к объекту const.

auto && выводится на const int &&, потому что вы не можете изменить содержимое initializer_list<int>: его begin() и end() методы возвращают const int *. Добавление std::move не работает, вы не можете обойти const вот так.

auto будет выводить на int, и будет работать: вы получите свежую не- constint локальную переменную i, содержащий копию значения в списке Инициализатора. Вы можете сформировать не const ссылки на эту локальную переменную.

Смежные вопросы