Привязка const rvalue к ссылке rvalue

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

В BST, в ctor, который принимает std :: initializer_list, я понимаю, что элементы std :: initializer_list могут копироваться только в соответствии с этот. Так что, если я не ошибаюсь, согласно Скотту Мейеру на недавнем GN13, выполнение перемещения объекта const вызовет только копирование-ctor объекта.

Вопрос 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;
}

0

Решение

Почему скобки терпят неудачу и пары init-brace успешны?

Потому что круглые скобки используются для объявлений функций. Вы не можете использовать их для инициализации переменных в области видимости класса. Четное int i(1); не сработает

Почему компилятор не может скопировать объект при вызове BST :: insert (T&& )

Вы не честны в сравнении. В вашем 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 ссылки на эту локальную переменную.

3

Другие решения


По вопросам рекламы [email protected]