【问题标题】:Perfectly capturing a perfect forwarder (universal reference) in a lambda在 lambda 中完美捕获完美转发器(通用参考)
【发布时间】:2015-10-03 07:14:34
【问题描述】:

所以我有一个完美的转发器,我想在 lambda 中适当地捕获它,以便复制 R 值,并通过引用捕获 L 值。然而,简单地使用 std::forward 并不能完成这项工作,正如这段代码所证明的那样:

#include<iostream>

class testClass
{
public:
   testClass() = default;
   testClass( const testClass & other ) { std::cout << "COPY C" << std::endl; }
   testClass & operator=(const testClass & other ) { std::cout << "COPY A" << std::endl; }
};

template< class T>
void testFunc(T && t)
   { [test = std::forward<T>(t)](){}(); }

int main()
{
   testClass x;
   std::cout << "PLEASE NO COPY" << std::endl;
   testFunc(x);
   std::cout << "DONE" << std::endl;

   std::cout << "COPY HERE" << std::endl;
   testFunc(testClass());
   std::cout << "DONE" << std::endl;
}

编译
g++ -std=c++14 main.cpp

产生输出

PLEASE NO COPY
COPY C
DONE
COPY HERE
COPY C
DONE

在一个完美的世界里,我只想让“COPY C”出现在右值的情况下,而不是左值的情况下。

我的解决方法是使用为 L- 和 R- 值重载的辅助函数,但我想知道是否有更好的方法。

干杯!

【问题讨论】:

  • Move capture in lambda的可能重复
  • @NirFriedman 这个问题解释了移动捕获和整个通用机制,但我认为它没有为完美转发捕获提供任何答案。直接的方法(OP 尝试过的)显然行不通。
  • @Angew 不错,我的错。向 OP 道歉。
  • 无需道歉 :-)

标签: c++ lambda perfect-forwarding


【解决方案1】:

您可以使用以下内容:

[test = std::conditional_t<
             std::is_lvalue_reference<T>::value,
             std::reference_wrapper<std::remove_reference_t<T>>,
             T>{std::forward<T>(t)}]

Live Demo

但提供辅助函数似乎更具可读性

【讨论】:

  • 看起来和其他任何东西一样好。很高兴知道我没有遗漏任何东西 :-) 谢谢。
  • 显然[&amp;t] 就足够了,前提是您在根据this在lambda主体内使用时转发t
  • 我的意思是假设适当的行为是移动右值和引用左值(我知道看到 OP 想要复制右值)
  • @LorahAttkins:这还假设 lambda 的生命周期比捕获的变量短。
猜你喜欢
  • 2015-01-06
  • 2020-12-04
  • 1970-01-01
  • 1970-01-01
  • 2017-08-05
  • 2014-08-23
  • 1970-01-01
  • 1970-01-01
  • 2022-07-21
相关资源
最近更新 更多