Click here to Skip to main content
15,880,608 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I'm just getting into move semantics, and from my reading it is only useful when a class 'new's something within it. Am I missing something, or does that make it so that if I want to eliminate the copying of an element upon returning from a function, one way to do so is to use a std::unique_ptr? For example, given the struct:

struct Triangle {
   POINT p1;
   POINT p2;
   POINT p3;
   };


If I want to return from a function that creates one, the best way to do so is something like the following:

std:unique_ptr<MouseHelper::Triangle> MouseHelper::makeTrianglePointingDown(int x, int y) {
   //The following is hard coded for the sizes I'm using in the example
   const int halfSize = 5;
   std:unique_ptr<Triangle> t(new Triangle);
   t->p1.x = x-halfSize;
   t->p1.y = y-halfSize-halfSize;

   t->p2.x = x+halfSize;
   t->p2.y = y-halfSize-halfSize;

   t->p3.x = x;
   t->p3.y = y-2;

   return t;
   }


Otherwise, I must make 'Triangle' into a class, and new a structure within that class, and then create an appropriate move constructor?

Thanks!

What I have tried:

Reading. And the above code works.
Posted
Updated 22-Mar-18 11:17am

The simplest way is returning the object by value, the compiler optimizes that (NRVO).
Try
C++
#include <iostream>
using namespace std;

struct Point
{
  int x, y;
};

struct Triangle
{
  Point p1,p2,p3;
  Triangle(){cout << "Triangle ctor" << endl;}
};

Triangle makeTrianglePointingDown(int x, int y)
{
   const int halfSize = 5;

   Triangle t;
   t.p1.x = x-halfSize;
   t.p1.y = y-halfSize-halfSize;

   t.p2.x = x+halfSize;
   t.p2.y = y-halfSize-halfSize;

   t.p3.x = x;
   t.p3.y = y-2;

   return t;
}

int main()
{
  Triangle tpd  = makeTrianglePointingDown(10,10);
  cout << tpd.p1.x << " " << tpd.p1.y << " ";
  cout << tpd.p2.x << " " << tpd.p2.y << " ";
  cout << tpd.p3.x << " " << tpd.p3.y << endl;
}
 
Share this answer
 
Comments
David O'Neil 22-Mar-18 17:26pm    
Thank you! In which cases can the compiler not use NRVO?
Maciej Los 23-Mar-18 15:17pm    
5ed!
If you want dynamic memory allocation, yes unique_ptr can be the solution.
But even if you simply return function local structure variable from the function, this can be done without a copying. Caller function can pre-allocate stack space and callee will just fill this space. And this memory block will be used after the call without a copying.
 
Share this answer
 
Comments
David O'Neil 22-Mar-18 16:32pm    
Can you show an example, or point to a site that shows the technique in C++?

Thanks!

Or are you saying that it is where the caller sends the address to be filled in in the arguments? I am not looking for that type of solution.
Rick York 22-Mar-18 17:01pm    
I believe what he is stating is you can pass a pointer into the function like this :

makeTrianglePointingDown( int x, int y, Triangle *pt );

and the pointer is the address of a stack object from the caller :

Triangle t;
makeTrianglePointingDown( x, y, &t );
David O'Neil 22-Mar-18 17:28pm    
That's what I guessed, which I wasn't interested in. Have performed too many calls to 'GetClientRect' that way... Boring...
[no name] 23-Mar-18 3:22am    
Hi! I meant the same stuff that in the solution #2. Compiler optimizes this through working with the same memory block in stack from the caller and callee.
David O'Neil 23-Mar-18 12:48pm    
Thanks!

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900