Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/139.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/apache/9.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++ 如何捕获std::unique“ptr”;“通过移动”;对于std::for_中的lambda_C++_Lambda_C++11 - Fatal编程技术网

C++ 如何捕获std::unique“ptr”;“通过移动”;对于std::for_中的lambda

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

我在学习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 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)
);