在实现 BS 树时,我注意到了一些自从我开始使用 C++11 智能指针以来我不太确定的事情,这让我想知道为什么会这样。如果我使用init-brace 对{}而不是括号,则下面的代码可以正常工作;我个人的规则是初始化每个成员(直接或通过ctor),并且由于Node::right和Node::left都是智能指针,因此nullptr它是。 问题 1:为什么括号失败而 init-brace 对成功?仅在这种情况下,两者之间是否存在语义差异?
在BST中,在采用 std::initializer_list 的 ctor 中,我知道 std::initializer_list 元素只能复制,根据this。因此,如果我没记错的话,根据最近 GN13 上的 Scott Meyer 的说法,对 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;
}