Skip to main content
added 316 characters in body
Source Link

You should make a couple of different tests and see what your compiler does with it. In the code above there are as many as 4 copies of the buffer:

  1. Inside GetData
  2. Return value of GetData
  3. Argument of constructor
  4. Member

The compiler by doing RVO/NRVO can merge 1 and 2 into a single object. Moreover it can merge those two objects with 3 by placing the three objects in the same memory location. What it cannot do is place that object and 4 in the same memory address (in the general case).

On that particular copy, you might elide it by default initializing the internal member vector (usually no cost) and swapping the contents of the argument with the member:

explicit Bar( Buffer buffer )  // pass by value if your compiler optimizes it
   : buffer_()                 // default construct: no cost
{
   buffer_.swap( buffer );     // swap: no cost 
};

Also note that this is the whole reason for rvalue references in the upcoming standard, in C++0x (I know that is not available in VS08) the compiler will use move semantics to avoid the copies while maintaining the code readable (readable as in closest to the intentions than to tricks to avoid the cost).

You should make a couple of different tests and see what your compiler does with it. In the code above there are as many as 4 copies of the buffer:

  1. Inside GetData
  2. Return value of GetData
  3. Argument of constructor
  4. Member

The compiler by doing RVO/NRVO can merge 1 and 2 into a single object. Moreover it can merge those two objects with 3 by placing the three objects in the same memory location. What it cannot do is place that object and 4 in the same memory address (in the general case).

On that particular copy, you might elide it by default initializing the internal member vector (usually no cost) and swapping the contents of the argument with the member:

explicit Bar( Buffer buffer )  // pass by value if your compiler optimizes it
   : buffer_()                 // default construct: no cost
{
   buffer_.swap( buffer );     // swap: no cost 
};

You should make a couple of different tests and see what your compiler does with it. In the code above there are as many as 4 copies of the buffer:

  1. Inside GetData
  2. Return value of GetData
  3. Argument of constructor
  4. Member

The compiler by doing RVO/NRVO can merge 1 and 2 into a single object. Moreover it can merge those two objects with 3 by placing the three objects in the same memory location. What it cannot do is place that object and 4 in the same memory address (in the general case).

On that particular copy, you might elide it by default initializing the internal member vector (usually no cost) and swapping the contents of the argument with the member:

explicit Bar( Buffer buffer )  // pass by value if your compiler optimizes it
   : buffer_()                 // default construct: no cost
{
   buffer_.swap( buffer );     // swap: no cost 
};

Also note that this is the whole reason for rvalue references in the upcoming standard, in C++0x (I know that is not available in VS08) the compiler will use move semantics to avoid the copies while maintaining the code readable (readable as in closest to the intentions than to tricks to avoid the cost).

Source Link

You should make a couple of different tests and see what your compiler does with it. In the code above there are as many as 4 copies of the buffer:

  1. Inside GetData
  2. Return value of GetData
  3. Argument of constructor
  4. Member

The compiler by doing RVO/NRVO can merge 1 and 2 into a single object. Moreover it can merge those two objects with 3 by placing the three objects in the same memory location. What it cannot do is place that object and 4 in the same memory address (in the general case).

On that particular copy, you might elide it by default initializing the internal member vector (usually no cost) and swapping the contents of the argument with the member:

explicit Bar( Buffer buffer )  // pass by value if your compiler optimizes it
   : buffer_()                 // default construct: no cost
{
   buffer_.swap( buffer );     // swap: no cost 
};