Ed *_*rbu 8 c++ future visual-c++ c++11 visual-c++-2012
考虑以下代码:
#include <memory>
#include <future>
using namespace std;
template <typename T, typename Work>
void Test2(future<T> f, Work w)
{
async([](future<T> && f, Work w)
{}, move(f), move(w));
}
int main()
{
future<int> x = std::async([]()->int{
std::this_thread::sleep_for(std::chrono::microseconds(200));
return 10;
});
Test2(std::move(x), [](int x){});
return 0;
}
Run Code Online (Sandbox Code Playgroud)
以上编译错误导致失败:
错误1错误C2664:'void Test2 :::: operator()(std :: future <_Ty> &&,Work)const':无法将参数1从'std :: future <_Ty>'转换为'std :: future <_Ty> &&'c:\ program files(x86)\ microsoft visual studio 11.0\vc\include\xrefwrap 98 1 ConsoleApplication6
GCC 4.7.2编译得很好 http://ideone.com/KhMiV6
在我继续并在Microsoft Connect上报告之前:
1)这是VC11的一个错误还是这个实际的标准行为?
2)有没有人知道这方面的解决方法?
编辑:我在这里的Microsoft Connect上报告了它.为了更快地解决问题,我们鼓励您进行投票.
小智 5
嗯,这似乎是VC11中的一个错误.显然,实现async
并不真正转发参数,而是复制它们.
从头顶开始,我将为rvalue创建一个小包装器,在复制包装器时移动构造元素:
template <typename T>
struct rvref_wrapper {
rvref_wrapper(T&& value) : value_(std::move(value)) {}
rvref_wrapper(rvref_wrapper const& other) : value_ (other.get()) {}
T&& get() const { return std::move(value_); }
mutable T value_;
};
template <typename T>
auto rvref(T&& x) -> rvref_wrapper<typename decay<T>::type> {
return std::move(x);
}
Run Code Online (Sandbox Code Playgroud)
然后你必须修改你的测试场景,以便lambda Test2
取得包装器而不是future
它自己:
template <typename T, typename Work>
void Test2(future<T> f, Work w)
{
async([](rvref_wrapper<future<T>> fr, Work w) {
// acquire future<T>&& here
future<T> f(fr.get());
// e.g. call work with future value
w(f.get());
}, rvref(f), move(w));
}
int main()
{
future<int> x = std::async([]()->int{
std::this_thread::sleep_for(std::chrono::microseconds(200));
return 10;
});
Test2(std::move(x), [](int x){});
return 0;
}
Run Code Online (Sandbox Code Playgroud)
看起来有点难看,但至少它编译.希望对你有所帮助!
归档时间: |
|
查看次数: |
831 次 |
最近记录: |