Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/161.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ std::将右值参考转发给lambda?_C++_Lambda_C++11_Forwarding_Rvalue Reference - Fatal编程技术网

C++ std::将右值参考转发给lambda?

C++ std::将右值参考转发给lambda?,c++,lambda,c++11,forwarding,rvalue-reference,C++,Lambda,C++11,Forwarding,Rvalue Reference,考虑以下两个片段: 附件A: template<typename CalcFuncT> int perform_calc(CalcFuncT&& calcfunc) { precalc(); int const calc = calcfunc(); postcalc(); return calc; } int main() { perform_calc([]{ return 5 * foobar_x() + 3; }); //

考虑以下两个片段:

附件A

template<typename CalcFuncT>
int perform_calc(CalcFuncT&& calcfunc)
{
    precalc();
    int const calc = calcfunc();
    postcalc();
    return calc;
}

int main()
{
    perform_calc([]{ return 5 * foobar_x() + 3; }); // toFuture
    perform_calc([]{ return 5 * foobar_y() - 9; }); // toPast
}
template<typename CalcFuncT>
int perform_calc(CalcFuncT&& calcfunc)
{
    precalc();
    int const calc = std::forward<CalcFuncT>(calcfunc)();
    postcalc();
    return calc;
}

int main()
{
    perform_calc([]{ return 5 * foobar_x() + 3; }); // toFuture
    perform_calc([]{ return 5 * foobar_y() - 9; }); // toPast
}
    precalc();
-   int const calc = calcfunc();
+   int const calc = std::forward<CalcFuncT>(calcfunc)();
    postcalc();
模板
int perform_calc(CalcFuncT&calcfunc)
{
预LC();
int const calc=calcfunc();
后计算();
返回计算;
}
int main()
{
执行计算([]{return 5*foobar_x()+3;});//toFuture
执行计算([]{return 5*foobar_y()-9;});//toPast
}
附件B

template<typename CalcFuncT>
int perform_calc(CalcFuncT&& calcfunc)
{
    precalc();
    int const calc = calcfunc();
    postcalc();
    return calc;
}

int main()
{
    perform_calc([]{ return 5 * foobar_x() + 3; }); // toFuture
    perform_calc([]{ return 5 * foobar_y() - 9; }); // toPast
}
template<typename CalcFuncT>
int perform_calc(CalcFuncT&& calcfunc)
{
    precalc();
    int const calc = std::forward<CalcFuncT>(calcfunc)();
    postcalc();
    return calc;
}

int main()
{
    perform_calc([]{ return 5 * foobar_x() + 3; }); // toFuture
    perform_calc([]{ return 5 * foobar_y() - 9; }); // toPast
}
    precalc();
-   int const calc = calcfunc();
+   int const calc = std::forward<CalcFuncT>(calcfunc)();
    postcalc();
模板
int perform_calc(CalcFuncT&calcfunc)
{
预LC();
int const calc=std::forward(calcfunc)();
后计算();
返回计算;
}
int main()
{
执行计算([]{return 5*foobar_x()+3;});//toFuture
执行计算([]{return 5*foobar_y()-9;});//toPast
}
Diff

template<typename CalcFuncT>
int perform_calc(CalcFuncT&& calcfunc)
{
    precalc();
    int const calc = calcfunc();
    postcalc();
    return calc;
}

int main()
{
    perform_calc([]{ return 5 * foobar_x() + 3; }); // toFuture
    perform_calc([]{ return 5 * foobar_y() - 9; }); // toPast
}
template<typename CalcFuncT>
int perform_calc(CalcFuncT&& calcfunc)
{
    precalc();
    int const calc = std::forward<CalcFuncT>(calcfunc)();
    postcalc();
    return calc;
}

int main()
{
    perform_calc([]{ return 5 * foobar_x() + 3; }); // toFuture
    perform_calc([]{ return 5 * foobar_y() - 9; }); // toPast
}
    precalc();
-   int const calc = calcfunc();
+   int const calc = std::forward<CalcFuncT>(calcfunc)();
    postcalc();
precalc();
-int const calc=calcfunc();
+int const calc=std::forward(calcfunc)();
后计算();
这两段代码的生成代码之间有什么区别(如果有)

换句话说,std::forward在上述情况下有什么影响(如果有)


注意:这个问题不是问std::forward通常做什么-只是问它在上面的上下文中做什么?

在调用操作符()之前,
forward
将lambda对象强制转换为xvalue。lambda对象的运算符()未使用“&&&”进行限定或重载,因此
向前
应该没有影响。

。我在那里使用
std::forward
,因为调用者不一定总是lambda(它可能是带有重载
操作符()的函子);如果调用方始终是lambda,那么使用
std::forward
@ildjarn:如何重载只能作为成员函数的
操作符()
s来区分右值
this
与左值
this
?这是C++11的新语法,在中引入,通俗称为“将移动语义扩展到*this”。本质上,
&
&
可以用作成员函数装饰器(除了通常的
常量和
volatile
)允许基于调用成员函数的对象的右值或左值进行重载。最好避免对函子的假设,例如用户将传递lambda。尽管右值限定的
运算符()
会很奇怪(意味着一次函子),例B当然更正确,因为它允许这种情况。