Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

So I have a perfect forwarder, and I want to appropriately capture it in a lambda, such that R-values are copied in, and L-values are captured by reference. However simply using std::forward doesn't do the job, as evidenced by this code:

#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;
}

Compiling this with

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

Produces the output

PLEASE NO COPY
COPY C
DONE
COPY HERE
COPY C
DONE

In a perfect world, I would like to only have the "COPY C" appear in the rvalue case, not the lvalue case.

My work around would be to use a helper function overloaded for L- and R- values, but I was wondering if there was a better way.

Cheers!

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
415 views
Welcome To Ask or Share your Answers For Others

1 Answer

You may use the following:

[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

but providing helper function seems more readable


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...