我遇到了将std :: moved unique_pointers返回到lambda的问题。一旦我将指针移动到lambda函数,我如何从lambda中取回所有权?
在下面的代码中,我正在演示我的问题。我从代码库中删除了一切并将所有内容都移到main来更好地解释问题。第一个问题被标记为“问题1” - 我想知道我是否正确使用(* v)访问我的向量。
代码创建一个数字向量,然后迭代向量以标记位图中的位。我认为这些位被正确标记,因为我能够在lambda本身中打印它们。在标记位之后,我想要归还所有权。我该怎么做?我需要将位图指针返回给调用函数。
如何从lambda以STANDARD方式取回所有权,而不是在传递的unique_ptr周围进行黑客攻击或避免将指针移动到lambda。 cpp17是否支持这个?
使用g ++ -std = c ++ 17
编译代码#include <memory>
#include <algorithm>
#include <iostream>
#include <vector>
int main () {
int increments = 10;
int numberOfElements = 10;
/* Create the vector */
auto v = std::make_unique<std::vector<int>>(std::vector<int> (numberOfElements));
/* QUESTION 1 - is (*v) the right way to access it or there is a better way. */
std::generate((*v).begin(), (*v).end(), [n=0, increments]() mutable { n = n + increments; return n;});
/* Print the generated elements */
std::cout << "\nPrinting the generated elements ";
std::for_each((*v).begin(), (*v).end(), [](int n) { std::cout<<" " << n;});
/* Int find the maximum element */
int maxElement = *(std::max_element((*v).begin(), (*v).end()));
/* Making a bitmap of the elements */
std::cout << "\nPrinting the maxElement " << maxElement;
auto bitmap = std::make_unique<std::vector <bool>> (std::vector<bool>(maxElement + 1));
/* Now setting all the elements in the vector to true in the bitmap. */
for_each((*v).begin(), (*v).end(), [bmap = std::move(bitmap)](int n) {
(*bmap).at(n) = true;
if ((*bmap).at(n) == true) {
std::cout << "\nBit "<< n <<" marked";
}
});
/*******************************************************
* Question 2 : I now need the ownership of bitmap back.
* How to do it ?. Bitmap is now null after moving it to the lambda.
*/
if (bitmap) {
std::cout << "\nafter reset, ptr is not NULL ";
} else if (bitmap == nullptr) {
std::cout << "\nbitmap is null";
}
}
答案 0 :(得分:0)
问题1 - 是(* v)访问它的正确方法,或者有更好的方法。
备选方案是使用->
,因此v->begin()
代替(*v).begin()
。
但unique_ptr
使用vector
很奇怪。
你可能只是这样做:
std::vector<int> v(numberOfElements);
std::generate(v.begin(), v.end(),
[n=0, increments]() mutable { n = n + increments; return n;});
std::cout << "\nPrinting the generated elements ";
for (int e : v) { std::cout << " " << e; };
int maxElement = *std::max_element(v.begin(), v.end());
// ...
问题2:我现在需要返回位图的所有权。怎么做?
你不能用lambda来做,在你的情况下通过引用捕获来完成工作(即使lambda拥有向量,for_each
“block”也没有):
std::vector<bool> bitmap(maxElement + 1);
for_each(v.begin(), v.end(), [&bmap](int n) {
bmap.at(n) = true;
std::cout << "\nBit "<< n <<" marked";
});
assert(!bitmap.empty());
if (bitmap.empty()) {
std::cout << "\nbitmap is empty";
} else if (bitmap == nullptr) {
std::cout << "\nbitmap is NOT empty";
}
如果用自己的仿函数替换lambda,可能会执行类似
的操作class MyMarker
{
public:
MyMarker(std::vector<bool>&& bitmap) : bitmap(std::move(bitmap)) {}
MyMarker(const MyMarker&) = delete;
MyMarker& operator =(const MyMarker&) = delete;
void operator() (int n) const
{
bitmap.at(n) = true;
std::cout << "\nBit "<< n <<" marked";
}
std::vector<bool> TakeBack() { return std::move(bitmap); }
private:
std::vector<bool> bitmap;
};
然后:
std::vector<bool> bitmap(maxElement + 1);
MyMarker myMarker(std::move(bitmap));
assert(bitmap.empty());
std::for_each(v.begin(), v.end(), myMarker);
bitmap = myMarker.TakeBack();
assert(!bitmap.empty());