[英]C++ pass vector (lvalue to rvalue)
Lets say you have 2 vectors
passed to a function as lvalue references
. 假设您有2个
vectors
作为lvalue references
传递给函数。 Later you realize, you can use recursion and pass slices of these vectors
using their iterators
. 后来您意识到,可以使用递归并使用它们的
iterators
传递这些vectors
切片。
Would it be an appropriate strategy if I go ahead and write some util
function to use these vecotrs
as rvalues
? 如果我继续编写一些
util
函数以将这些vecotrs
用作rvalues
那将是一种适当的策略吗? Or I should avoid this in any way? 还是我应该以任何方式避免这种情况?
Simplified pattern: 简化模式:
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() });
}
Realistic example ( LeetCode 105 ): 实际示例 ( LeetCode 105 ):
TreeNode* util(vector<int>&& preorder, vector<int>&& inorder) {
if (!preorder.empty()) {
TreeNode* root = new TreeNode(preorder[0]);
auto r = find(inorder.begin(), inorder.end(), preorder[0]);
root->left = util(
{ preorder.begin() + 1, preorder.begin() + 1 + distance(inorder.begin(), r) },
{ inorder.begin(), r });
root->right = util(
{ preorder.begin() + 1 + distance(inorder.begin(), r), preorder.end() },
{ r + 1, inorder.end() });
return root;
}
return nullptr;
}
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
return util({ preorder.begin(), preorder.end() },
{ inorder.begin(), inorder.end() });
}
You are on the wrong way: {a.begin(), a.end()}
is equivalent to std::vector<int>(a.begin(), a.end())
, ie calls the constructor accepting two iterators, which copies all data in between these two iterators, ie the whole vector in your case (or sub-ranges of the vector in your more realistic example). 您使用的是错误的方式:
{a.begin(), a.end()}
等同于std::vector<int>(a.begin(), a.end())
,即调用接受两个迭代器,它在这两个迭代器之间复制所有数据,即您所用的整个向量(或者在更实际的示例中为向量的子范围)。
But you don't modify the vectors in any way, so no need for any copies. 但是您不会以任何方式修改向量,因此不需要任何副本。
If you just want to read the original vector, then you can work directly with iterators; 如果您只想读取原始向量,则可以直接使用迭代器。 you can pass these by value, unter the hoods, they are more or less just pointers into the vector's data anyway:
您可以按值传递这些参数,无论如何,它们或多或少只是指向向量数据的指针:
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);
// ...
}
const_iterator
? const_iterator
? Well, we want to accept const
vectors: 好吧,我们要接受
const
向量:
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...
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.