简体   繁体   English

Visual Studio 2013 C ++ - 将std :: unique_ptr传递给绑定函数

[英]Visual Studio 2013 C++ - Passing std::unique_ptr to a bound function

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 . 使用Visual Studio 2013 RC和C ++,我试图将std::unique_ptr传递给已使用std::bind的函数。 However, I'm having trouble because VS doesn't seem to like it when I try this. 但是,我遇到了麻烦,因为当我尝试这个时,VS似乎并不喜欢它。 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. 这在GCC 4.8.1中编译,但在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. 我总是遇到VS中移动语义的问题,但我真的很想使用std::unique_ptr而不是std::shared_ptr或原始指针。

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: 我找到的一个解决方法是更改​​函数签名以接受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> 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? 有没有办法绕过这个而不改变func的签名?

Thanks! 谢谢!

I had the same problem with VS 2012 recently. 我最近和VS 2012有同样的问题。 I believe this is a bug in MSVC; 我相信这是MSVC中的一个错误; at least in MSVC++11 the pseudo-variadic expansion seems to forward the parameters by value to some internal function. 至少在MSVC ++ 11中,伪可变参数扩展似乎通过值将参数转发给某些内部函数。 Seems this hasn't been improved. 似乎这没有得到改善。
As a workaround, I'm using lambdas instead, but another hack is required to make it work: 作为一种解决方法,我正在使用lambdas,但需要另一个hack来使其工作:

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)); };

You have to move the parameter into the bound call to func also. 您还必须将参数移动到func的绑定调用中。 Not only in the invocation of bound 不仅在bound的调用

bound(std::move(ptr));

but also in the binding: 而且在绑定中:

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

This is compiling in VS2013 (update 4) for me. 这是为VS2013(更新4)编译的。

Functions bound with std::bind do not forward arguments, it copies them to the function. std::bind函数不转发参数,它将它们复制到函数中。 As a result, std::bind doesn't work with move-only types as of c++11. 因此,从c ++ 11开始, std::bind不适用于仅移动类型。 This problem is the idea behind proposals for "more perfect forwarding" ( like this one ). 这个问题是“更完美转发”提案背后的想法( 就像这个 )。 There's a newer one, but I can't seem to find it right now. 有一个更新的,但我现在似乎无法找到它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM