C++ 传递到std::result_之前的衰减类型
如本页所示,C++14中的C++ 传递到std::result_之前的衰减类型,c++,templates,c++11,c++14,C++,Templates,C++11,C++14,如本页所示,C++14中的std::async的签名之一已从C++11版本更改 template< class Function, class... Args> std::future<typename std::result_of<Function(Args...)>::type> async( Function&& f, Args&&... args ); 将打印出四个trues.更改响应。问题是async(如bi
std::async
的签名之一已从C++11版本更改
template< class Function, class... Args>
std::future<typename std::result_of<Function(Args...)>::type>
async( Function&& f, Args&&... args );
将打印出四个
true
s.更改响应。问题是async
(如bind
等)decay复制了它的所有参数,因此如果在返回类型中没有使用decay
,那么在涉及ref限定和/或rvalue时,您将得到错误的返回类型:
struct F {
int operator()() &;
char operator()() &&;
int operator(int& ) const;
char operator(int&& ) const;
};
auto future = std::async(F{}); // actually gives future<int>, but says
// it gives future<char>?
auto future2 = std::async(F{}, 1); // ditto
struct F{
int运算符()()&;
char运算符()()&;
int运算符(int&)const;
字符运算符(int&&)常量;
};
auto future=std::async(F{});//实际上给未来,但是说
//它给了未来?
autofuture2=std::async(F{},1);//同上
由于async的所有参数都被构造到其内部对象中,因此需要巧妙地包装它们,以便实际实现参数的右值
这是有意义的-
async
必须将其参数存储在某个位置,如果传入右值,则它必须拥有这些参数的所有权。如果它持有右值引用,底层对象可能会被破坏。但是,一旦它将其存储为T
,它就不知道它来自T&
或T&
——在这一点上它只有一个命名的左值参数 我认为它对引用函数类型有意义。@101010没有decay
删除引用限定?@101010请查看我的更新。啊。这就是为什么我们真正喜欢C++的原因。请注意,新版本意味着它<代码>移动< /代码> s,将其内部存储的函数和参数转换为调用表达式,这也是正确的事情。@ yAK不同于“代码> bDand())/>代码>的语义使它非常混乱。我意识到线程/异步是一个调用,而bind可能是多个调用,但它仍然是。。。混淆。这就是为什么bind
需要一个右值重载的操作符()
和一个左值重载的操作符()
来处理这个问题。与lambdas类似:在右值上下文中,他们可能应该在最后一次使用时将其本地状态视为右值。另一方面,不确定如何使语法安全、不出人意料且高效,因此。。。(这并不奇怪!)@ZizhengTai,因为他们是以右值的形式搬进来的。如果您不decay\u t
,您将检查返回类型,就像它们可能是左值一样。
#include <iostream>
#include <type_traits>
int main()
{
auto fn = [](auto x) -> int { return x + 1; };
using Fn = decltype(fn);
using FnRef = Fn&;
using FnCRef = const Fn&;
using FnRRef = Fn&&;
std::cout << std::boolalpha
<< std::is_same<int, std::result_of_t<Fn(int)>>::value << '\n'
<< std::is_same<int, std::result_of_t<FnRef(int)>>::value << '\n'
<< std::is_same<int, std::result_of_t<FnCRef(int)>>::value << '\n'
<< std::is_same<int, std::result_of_t<FnRRef(int)>>::value << '\n';
return 0;
}
struct F {
int operator()() &;
char operator()() &&;
int operator(int& ) const;
char operator(int&& ) const;
};
auto future = std::async(F{}); // actually gives future<int>, but says
// it gives future<char>?
auto future2 = std::async(F{}, 1); // ditto