Visual Studio 2013 C ++ - 将std :: unique_ptr传递给绑定函数 [英] Visual Studio 2013 C++ - Passing std::unique_ptr to a bound function

查看:372
本文介绍了Visual Studio 2013 C ++ - 将std :: unique_ptr传递给绑定函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用Visual Studio 2013 RC和C ++,我试图传递一个 std :: unique_ptr 到一个函数已绑定使用 std :: bind 。但是,我有麻烦,因为VS似乎不喜欢,当我试试这个。这里是我想要编译:

  #include< memory> 
#include< iostream>
#include< functional>

void func(std :: unique_ptr< int> arg)
{
std :: cout< * arg<< std :: endl;
}

int main()
{
std :: function< void(std :: unique_ptr< int>)> bound =
std :: bind(& func,std :: placeholders :: _ 1);

std :: unique_ptr< int> ptr(new int(42));
bound(std :: move(ptr));

return 0;
}

这在GCC 4.8.1中编译,但不在VS2013 RC中编译。我一直在VS中移动语义的问题,但我真的想使用 std :: unique_ptr 而不是 std :: shared_ptr 或原始指针。



一个解决方法我发现是更改函数签名接受 std :: unique_ptr& ; ,它在VS和GCC中编译,但不会使 func 的意图取得 std :: unique_ptr 特别清楚,也阻止我安全异步调用函数,除非我做一些特别丑陋的事情:

  #include< memory> 
#include< iostream>
#include< functional>
#include< future>
#include< string>

void func(std :: unique_ptr< int>& arg)
{
std :: cout< * arg<< std :: endl;
}

int main()
{
std :: function< void(std :: unique_ptr< int>& bound =
std :: bind(& func,std :: placeholders :: _ 1);

std :: unique_ptr< int> ptr(new int(42));
std :: promise< void>舞会;
std :: async(
[& bound,& ptr,& prom]
{
std :: unique_ptr< int> movedPtr = std :: move );
prom.set_value();

bound(std :: move(movedPtr));
});

prom.get_future()。wait();

//等待这里
std :: string dummy;
std :: cin>>假;
}

有没有办法改变 func 的签名?



谢谢!

解决方案>

我最近有VS 2012的同样的问题。我相信这是MSVC中的一个错误;至少在MSVC ++ 11中,伪可变扩展似乎通过值将参数转发到某些内部函数。

作为一种解决方法,我使用lambdas代替,但需要另一个黑客来使它工作:

  std :: function< void(std :: unique_ptr< int>)> bound = 
[](std :: unique_ptr< int> arg){func(std :: move };

仍然无法编译。但是如果你添加任何捕获的值(即使没有使用),它会编译:

  int x; 
std :: function< void(std :: unique_ptr< int>)> bound =
[x](std :: unique_ptr< int> arg){func(std :: move };


Using Visual Studio 2013 RC and C++, I'm trying to pass an std::unique_ptr to a function that has been bound using std::bind. However, I'm having trouble because VS doesn't seem to like it when I try this. Here's what I'm trying to compile:

#include <memory>
#include <iostream>
#include <functional>

void func(std::unique_ptr<int> arg)
{
    std::cout << *arg << std::endl;
}

int main()
{
    std::function<void (std::unique_ptr<int>)> bound =
        std::bind(&func, std::placeholders::_1);

    std::unique_ptr<int> ptr(new int(42));
    bound(std::move(ptr));

    return 0;
}

This compiles in GCC 4.8.1, but not in VS2013 RC. I've always had problems with move semantics in VS, but I'd really like to use std::unique_ptr instead of std::shared_ptr or raw pointers.

One workaround I've found is to change the function signature to accept an std::unique_ptr&, which does compile in VS and GCC, but doesn't make the intent of func taking ownership of the std::unique_ptr particularly clear, and also prevents me from safely asynchronously calling the function unless I do something particularly ugly:

#include <memory>
#include <iostream>
#include <functional>
#include <future>
#include <string>

void func(std::unique_ptr<int>& arg)
{
    std::cout << *arg << std::endl;
}

int main()
{
    std::function<void (std::unique_ptr<int>&)> bound =
        std::bind(&func, std::placeholders::_1);

    std::unique_ptr<int> ptr(new int(42));
    std::promise<void> prom;
    std::async(
        [&bound, &ptr, &prom]
        {
            std::unique_ptr<int> movedPtr = std::move(ptr);
            prom.set_value();

            bound(std::move(movedPtr));
        });

    prom.get_future().wait();

    // Wait here
    std::string dummy;
    std::cin >> dummy;
}

Is there a way to get around this without changing func's signature?

Thanks!

解决方案

I had the same problem with VS 2012 recently. I believe this is a bug in MSVC; at least in MSVC++11 the pseudo-variadic expansion seems to forward the parameters by value to some internal function. Seems this hasn't been improved.
As a workaround, I'm using lambdas instead, but another hack is required to make it work:

std::function<void (std::unique_ptr<int>)> bound =
    [] (std::unique_ptr<int> arg) { func(std::move(arg)); };

still doesn't compile. But if you add any captured value (even one that isn't used), it compiles:

int x;
std::function<void (std::unique_ptr<int>)> bound =
    [x] (std::unique_ptr<int> arg) { func(std::move(arg)); };

这篇关于Visual Studio 2013 C ++ - 将std :: unique_ptr传递给绑定函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆