Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/cocoa/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;传递向量(从左值到右值)_C++_Vector_Rvalue_Lvalue_Lvalue To Rvalue - Fatal编程技术网

C++ C++;传递向量(从左值到右值)

C++ C++;传递向量(从左值到右值),c++,vector,rvalue,lvalue,lvalue-to-rvalue,C++,Vector,Rvalue,Lvalue,Lvalue To Rvalue,假设有2个向量作为左值引用传递给函数。后来您意识到,您可以使用递归并使用它们的迭代器传递这些向量的切片 如果我继续编写一些util函数,将这些vecotr用作rvalues,这是一种合适的策略吗?或者我应该以任何方式避免这种情况 简化模式: Node* util(vector<int>&& a, vector<int>&& b) { Node* root = new Node(a[0]); root->left =

假设有2个
向量作为
左值引用
传递给函数。后来您意识到,您可以使用递归并使用它们的
迭代器传递这些
向量的切片

如果我继续编写一些
util
函数,将这些
vecotr
用作
rvalues
,这是一种合适的策略吗?或者我应该以任何方式避免这种情况

简化模式:

Node* util(vector<int>&& a, vector<int>&& b) {
    Node* root = new Node(a[0]);

    root->left = util({ a.begin(), a.end() }, { b.begin(), b.end() });
    root->right = util({ a.begin(), a.end() }, { b.begin(), b.end() });

    return root;
}

Node* main(vector<int>& a, vector<int>& b) {
    return util({ a.begin(), a.end() }, { b.begin(), b.end() });
}
Node*util(向量和a、向量和b){
Node*root=新节点(a[0]);
root->left=util({a.begin(),a.end()},{b.begin(),b.end()});
root->right=util({a.begin(),a.end()},{b.begin(),b.end()});
返回根;
}
节点*主节点(向量和a、向量和b){
返回util({a.begin(),a.end()},{b.begin(),b.end()});
}
现实例子():

TreeNode*util(向量和预序、向量和索引序){
如果(!preorder.empty()){
树节点*根=新树节点(前序[0]);
auto r=find(inoorder.begin()、inoorder.end()、preorder[0]);
root->left=util(
{preorder.begin()+1,preorder.begin()+1+距离(inoorder.begin(),r)},
{inorder.begin(),r});
root->right=util(
{preorder.begin()+1+距离(inoorder.begin(),r),preorder.end()},
{r+1,inorder.end()});
返回根;
}
返回空ptr;
}
TreeNode*构建树(向量和前序,向量和索引){
返回util({preorder.begin(),preorder.end()},
{inoorder.begin(),inoorder.end()});
}

您走错了:
{a.begin(),a.end()}
相当于
std::vector(a.begin(),a.end())
,i。E调用接受两个迭代器的构造函数,该构造函数复制这两个迭代器之间的所有数据,即。E案例中的整个向量(或更现实示例中向量的子范围)

但是,您不以任何方式修改向量,因此不需要任何副本

如果您只想读取原始向量,那么您可以直接使用迭代器;您可以通过值传递这些值,卸下防护罩,它们或多或少只是指向向量数据的指针:

TreeNode* util
(
    vector<int>::const_iterator preorderBegin, vector<int>::const_iterator preorderEnd,
    vector<int>::const_iterator inorderBegin, vector<int>::const_iterator inorderEnd
)
{
    // ...
    ++preorderBegin; // if we do so before the call, we have just one addition; compiler
                     // might optimize to the same code, but we don't rely on it this way
    util(preorderBegin, preorderBegin + distance(), inorderBegin, r);
    // ...
}

我不明白为什么需要r值引用(是否要移动任何数据??),普通引用也可以。由于您似乎没有修改输入向量,常量引用将是合适的。这不是为每个参数构造一个全新的向量吗?右值无法阻止这种情况的发生。我无法用普通引用传递向量迭代器。此语法
root->left=util({a.begin(),a.end()},{b.begin(),b.end()})不会work@TharwenWas我也正准备修改我之前的评论。。。是的,我们在副本之上创建副本,而从不修改它们。所以:const引用了我前面的注释,只是递归地调用
util(preorder,inoorder)
应该非常好。@user2376997您可以按值传递迭代器;在这种情况下,你或多或少只是把指针传递到数据中。。。提供迭代器作为util函数的参数,您可以这样做
{a.begin(),a.end()}
相当于std::vector(a.begin(),a.end())
,i。E调用接受两个迭代器的构造函数,该构造函数复制这两个迭代器之间的所有数据,即。E在你的例子中,整个向量。
TreeNode* util
(
    vector<int>::const_iterator preorderBegin, vector<int>::const_iterator preorderEnd,
    vector<int>::const_iterator inorderBegin, vector<int>::const_iterator inorderEnd
)
{
    // ...
    ++preorderBegin; // if we do so before the call, we have just one addition; compiler
                     // might optimize to the same code, but we don't rely on it this way
    util(preorderBegin, preorderBegin + distance(), inorderBegin, r);
    // ...
}
TreeNode* buildTree(vector<int> const& preorder, vector<int> const& inorder)
//                                ^                            ^
// you don't modify the vectors, so accept them as constant
{
    return util(preorder.begin(), preorder.end(), inorder.begin(), inorder.end());
    // note the dropped braces...
}