【问题标题】:calling perfectly forwarded lambda调用完美转发的 lambda
【发布时间】:2026-01-09 10:05:01
【问题描述】:

我有以下类,它存储了对函数的完美转发引用:

template <class F> 
class Visitor
{
public:
    Visitor(F &&f) : _f(std::forward<F>(f)) 
    {
    }

    xt::LOOP_CONTROL OnElem(xvi::Elem &elem)
    {
        return _f(elem);

        // or should it be: 
        // return std::forward<F>(_f)(elem);
    }

private:
    F &&_f;
};

想知道拨打_f(elem)std::forward&lt;F&gt;(_f)(elem); 是否会有所不同?

【问题讨论】:

  • 通常你会转发参数,而不是函数本身。
  • 尽管技术上可以通过引用operator() 来处理左值或右值,但我认为它在实践中的表现并不多。 _f(elem) 被破坏的可能性很小。

标签: c++ forwarding perfect


【解决方案1】:

Lambda 目前不能有 ref 限定 operator (),所以对他们来说,这两种形式是等价的。

对于自定义函子,它可能与 std::forward&lt;F&gt;(_f)(elem); 不同:

struct MyFunctor
{
    xt::LOOP_CONTROL operator()(xvi::Elem &elem) &  { std::cout << "lvalue"; return {};}
    xt::LOOP_CONTROL operator()(xvi::Elem &elem) && { std::cout << "rvalue"; return {};}
};

xvi::Elem elem;
Visitor<MyFunctor>(MyFunctor{}).OnElem(elem); // rvalue
MyFunctor func;
Visitor<MyFunctor&>(func).OnElem(elem); // lvalue

【讨论】:

  • 非常感谢您的回答,我还没有看到需要 ref 限定函数,但也许有一天这会派上用场。
  • 我看到的一个可能有用的,它允许延长生命周期 auto&amp;&amp; extended = Tmp().getObj();Obj getObj() &amp;&amp;(此处按值返回以允许延长生命周期)/Obj&amp; getObj() &amp;/const Obj&amp; getObj() const &amp;
  • 再次感谢@Jarod42,这是一个很好的用例。