C++ 如何捕获std::unique“ptr”;“通过移动”;对于std::for_中的lambda
我在学习c++11的新特性时遇到了这个问题。我想通过将其移动到lambda中作为每个参数来捕获一个唯一的\u ptr 设立:C++ 如何捕获std::unique“ptr”;“通过移动”;对于std::for_中的lambda,c++,lambda,c++11,C++,Lambda,C++11,我在学习c++11的新特性时遇到了这个问题。我想通过将其移动到lambda中作为每个参数来捕获一个唯一的\u ptr 设立: std::array<int,4> arr = {1,3,5,6}; std::unique_ptr<int> p(new int); (*p) = 3; 尝试2-使用bind将p的移动副本绑定到接受int&: std::for_each(arr.begin(), arr.end(), std::bind([](const uniqu
std::array<int,4> arr = {1,3,5,6};
std::unique_ptr<int> p(new int); (*p) = 3;
尝试2-使用bind将p的移动副本绑定到接受int&:
std::for_each(arr.begin(), arr.end(),
std::bind([](const unique_ptr<int>& p, int& i){
i += (*p);
}, std::move(p))
);
std::for_each(arr.begin(),arr.end(),
std::bind([](常量唯一\u ptr&p、int&i){
i+=(*p);
},std::move(p))
);
编译器抱怨“结果”:符号既不是类模板也不是函数模板。
本练习的主要目的是了解如何在缓存以供以后使用的lambda中捕获可移动变量。更新:从C++14开始,您可以在lambda中捕获可移动变量
std::for_each(arr.begin(), arr.end(), [p=std::move(p)](int& i) { i+=*p; });
在C++11中,不能以任何直接的方式将可移动变量捕获到lambda中 Lambdas通过复制或引用捕获。因此,要捕获仅移动的变量,必须将其包装在一个对象中,其中copying=>moving(例如
std::auto_ptr
)。这是一个令人讨厌的黑客行为
在您的示例中,您可以仅通过引用捕获,但如果这只是简化的代码,则可能无法使用实际代码实现您想要的功能:
std::for_each(arr.begin(), arr.end(), [&p](int& i) { i+=*p; });
这是一个仅复制移动的包装器:
template<typename T>
struct move_on_copy_wrapper
{
mutable T value;
move_on_copy_wrapper(T&& t):
value(std::move(t))
{}
move_on_copy_wrapper(move_on_copy_wrapper const& other):
value(std::move(other.value))
{}
move_on_copy_wrapper(move_on_copy_wrapper&& other):
value(std::move(other.value))
{}
move_on_copy_wrapper& operator=(move_on_copy_wrapper const& other)
{
value=std::move(other.value);
return *this;
}
move_on_copy_wrapper& operator=(move_on_copy_wrapper&& other)
{
value=std::move(other.value);
return *this;
}
};
模板
结构在包装上移动包装
{
可变T值;
在包装上移动(T&&T):
值(标准::移动(t))
{}
在包装上移动包装(在包装上移动包装常数和其他):
值(标准::移动(其他值))
{}
在复制包装上移动(在复制包装上移动(&O):
值(标准::移动(其他值))
{}
move_on_copy_wrapper&operator=(move_on_copy_wrapper const&other)
{
值=标准::移动(其他.value);
归还*这个;
}
move_on_copy_wrapper&operator=(move_on_copy_wrapper&other)
{
值=标准::移动(其他.value);
归还*这个;
}
};
然后您可以这样使用它:
int main()
{
std::unique_ptr<int> p(new int(3));
move_on_copy_wrapper<std::unique_ptr<int>> mp(std::move(p));
[mp]()
{
std::cout<<"*mp.value="<<*mp.value<<std::endl;
}
();
std::cout<<"p="<<p.get()<<", mp="<<mp.value.get()<<std::endl;
}
intmain()
{
std::unique_ptr p(新int(3));
在包装器mp上移动(标准::移动(p));
[mp]()
{
std::cout您的尝试2几乎可以成功
缺少的是您没有告诉您的bind
调用需要一个参数:
std::for_each(arr.begin(), arr.end(),
std::bind([](const unique_ptr<int>& p, int& i){
i += (*p);
}, std::move(p), std::placeholders::_1)
);
std::for_each(arr.begin(),arr.end(),
std::bind([](常量唯一\u ptr&p、int&i){
i+=(*p);
},std::move(p),std::占位符::_1)
);
占位符::_1
用于告诉bind
的结果,它应该期望为其运算符()传递一个参数
这也是@marton78的答案中给出的建议。这个问题已经被问过了。但是,我不赞成结束,因为你的问题包含了一个替代的解决方案(尽管不起作用)。另请参见。你真的需要实现移动语义功能吗,即move_on_copy_wrapper(move_on_copy_wrapper&)
和move_on_copy_wrapper&operator=(move_on_copy_wrapper&&)
编译器生成的参数不够?编译器不会生成它们,因为存在复制构造函数和复制赋值运算符。“注意std::bind还要求其参数是可复制的。”那不是真的。std::bind
可用于仅移动类型。AFAIK,std::bind应适用于可移动参数。然而,MSDN的文档说明所有参数都应可复制构造。Anthony,您使用哪种编译器?好的,我选中了:std::bind
应可用于仅移动参数,它只创建了仅移动参数然而,它在MSVC2010和g++4.7的实际应用中失败了。
std::for_each(arr.begin(), arr.end(),
std::bind([](const unique_ptr<int>& p, int& i){
i += (*p);
}, std::move(p), std::placeholders::_1)
);