[英]Binding const rvalue to rvalue reference
在实现BS树时,由于我开始使用C ++ 11智能指针,我注意到了一些不确定的事情,这让我想知道为什么会这样。 如果我使用init-brace pair {}而不是括号,则下面的代码可以正常工作; 我个人的规则是(直接或通过ctor)对每个成员进行值初始化,并且由于Node :: right和Node :: left都是智能指针,因此, nullptr是。 问题1 :为什么括号会失败,而括号对会成功? 仅在这种情况下,两者之间在语义上有什么区别吗?
在BST,在其采用的std :: initializer_list的构造函数,我明白的std :: initializer_list元素仅可复制,根据这个 。 因此,根据最近的GN13的斯科特·迈耶(Scott Meyer)的说法,如果我没记错,对const对象执行移动只会触发该对象的copy-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;
}
为什么括号会失败,而括号对会成功?
因为括号用于函数声明。 您不能使用它们在类范围内初始化变量。 甚至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
引用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.