Visual Studio 2013 C++ - 将 std::unique_ptr 传递给绑定函数
使用 Visual Studio 2013 RC 和 C++,我试图将 std::unique_ptr
传递给使用 std::bind
绑定的函数.但是,我遇到了麻烦,因为当我尝试这个时 VS 似乎并不喜欢它.这是我要编译的内容:
#include #include #include <功能>void func(std::unique_ptr arg){std::cout <<*arg<)>界 =std::bind(&func, std::placeholders::_1);std::unique_ptrptr(new int(42));边界(标准::移动(ptr));返回0;}
这可以在 GCC 4.8.1 中编译,但不能在 VS2013 RC 中编译.我总是在 VS 中遇到移动语义的问题,但我真的很喜欢使用 std::unique_ptr
而不是 std::shared_ptr
或原始指针.>
我发现的一种解决方法是更改??函数签名以接受 std::unique_ptr&
,它确实在 VS 和 GCC 中编译,但不符合 的意图func
特别清楚地获得 std::unique_ptr
的所有权,并且还阻止我安全地异步调用该函数,除非我做了一些特别难看的事情:
#include #include #include <功能>#include <未来>#include <字符串>void func(std::unique_ptr<int>&arg){std::cout <<*arg<&)>界 =std::bind(&func, std::placeholders::_1);std::unique_ptrptr(new int(42));std::promise舞会;标准::异步([&bound、&ptr、&prom]{std::unique_ptrmovedPtr = std::move(ptr);prom.set_value();边界(标准::移动(移动Ptr));});prom.get_future().wait();//在这里等候std::string 虚拟对象;std::cin >>假;}
有没有办法在不改变func
的签名的情况下解决这个问题?
谢谢!
解决方案我最近在使用 VS 2012 时遇到了同样的问题.我相信这是 MSVC 中的一个错误;至少在 MSVC++11 中,伪可变参数扩展似乎将参数按值转发给某个内部函数.似乎这没有得到改善.
作为一种解决方法,我使用 lambdas,但需要另一个 hack 才能使其工作:
std::function)>界 =[] (std::unique_ptr arg) { func(std::move(arg));};
仍然无法编译.但是,如果您添加任何捕获的值(即使是未使用的值),它也会编译:
int x;std::function)>界 =[x] (std::unique_ptr arg) { func(std::move(arg));};
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)); };
相关文章