使用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
的意图取得{的所有权{1}}特别清楚,并且还阻止我安全地异步调用函数,除非我做一些特别难看的事情:
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;
}
的签名?
谢谢!
答案 0 :(得分:2)
我最近和VS 2012有同样的问题。我相信这是MSVC中的一个错误;至少在MSVC ++ 11中,伪可变参数扩展似乎通过值将参数转发给某些内部函数。似乎这没有得到改善。
作为一种解决方法,我正在使用lambdas,但需要另一个hack才能使它工作:
std::function<void (std::unique_ptr<int>)> bound =
[] (std::unique_ptr<int> arg) { func(std::move(arg)); };
仍然无法编译。但是如果添加任何捕获的值(即使是未使用的值),它也会编译:
int x;
std::function<void (std::unique_ptr<int>)> bound =
[x] (std::unique_ptr<int> arg) { func(std::move(arg)); };
答案 1 :(得分:1)
您还必须将参数移动到func
的绑定调用中。不仅在bound
bound(std::move(ptr));
但也在绑定中:
std::function<void(std::unique_ptr<int>)> bound =
std::bind(func,
std::bind(std::move<std::unique_ptr<int>&>,
std::placeholders::_1));
这是我在VS2013(更新4)中编译的。
答案 2 :(得分:0)
与std::bind
绑定的函数不转发参数,它将它们复制到函数中。因此,std::bind
不适用于c ++ 11中的仅移动类型。这个问题是“更完美转发”(like this one)提案背后的想法。有一个更新的,但我现在似乎无法找到它。