Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

proper use of std move for a factory class

I want to create a factory class like below, but I am not confident this is the right way to use std::move. I don't want to use too many shared_ptrs, since shared_ptr inside another shared_ptr is really ugly and sometimes confusing...

Option 1:

class Foo
{
  public:
  Foo(Foo&& f){...}
}

class FooFactory
{
   public:
     static Foo&& createFoo(...)
     {
       Foo temp(...);
       return std::move(temp);
     }
}

main()
{
   Foo f=FooFactory::createFoo(...);
}

Option 2:

class FooFactory
{
   public:
     static Foo createFoo(...)
     {
       Foo temp(...);
       return temp;
     }// rely on compiler for optimization
}

main()
{
   Foo f=std::move(FooFactory::createFoo(...));
}
like image 847
Michael Avatar asked Feb 19 '15 11:02

Michael


1 Answers

The correct way to do this is option 3 (aka same as before):

class FooFactory
{
   public:
     static Foo createFoo(...)
     {
       Foo temp(...);
       return temp;
     }
};

int main()
{
   Foo f=FooFactory::createFoo(...);
}

temp is already treated as an rvalue in return temp;. No std::move is necessary; similarly FooFactory::createFoo(...); is already an rvalue, so you don't need std::move either. In fact, in either case, using std::move is a pessimization because it inhibits move elision.

Your option 1 is not only inefficient but incorrect, as it returns a dangling reference to temp.

like image 109
T.C. Avatar answered Oct 07 '22 16:10

T.C.