Ben FrantzDale (benfrantzdale) wrote,

C++0x!

After helping 3M move Lava C.O.S. to a great new team in St. Paul, I've started work with someone new project which involves some C++ programming, this time with Visual Studio 2010, which includes several important C++0x features I had been introduced to in David Musser's Generic Programming course in grad school.

The most interesting (and at first baffling) is rvalue references. They have the dubious syntax of && but are not a reference to a reference (whatever that would mean); it is a special type of reference that at compile time is known to be basically an unnamed temporary. Having this distinction lets you do a number of interesting optimizations related to moving objects around; so-called move semantics.



Suppose a function has returned to you a std::vector<int>, as in:
std::vector<int> x = makeGiantVector();

Now, the compiler may be able to optimize that, but it can't always. When it can't you have to construct a new vector<int>, copy every element from the temporary that was returned, then delete the memory of the temporary. Since std::vector is heap-allocated, you would like to have the above line act like this:
std::vector<int> tmp;
makeGiantVectorByReference(tmp);
std::vector<int> x;

std::swap(tmp, x);



That is, we want to be able to steal the memory used by the temporary rather than copy it only to delete it. C++0x does this by letting temporaries like the values returned from a function bind to an "rvalue reference", so std::vector can have a constructor that takes temporaries and steals the memory. This is safe because the compiler only gives you rvalue references to temporaries. The constructors look like this:
vector(const vector& v) {

  _beg = new T[v.size()];
  _end = _beg + v.size();

  _endOfStorage = _end;
  copy(v.begin(), v.end(), begin());
}

vector(vector&& v) : 
  _beg(v._beg), 
  _end(v._end), 
  _endOfStorage(v._endOfStorage) 
{

  if (this != &v) {
    v._beg = NULL;

    v._end = NULL;
    v._endOfStorage = NULL;
  }
}


You can also overload the assignment operator with an rvalue reference, of course.

This is a nice optimization. The neat part is that this one feature gives you the ability to move things:
std::vector<int> x = foo();
std::vector<int> y = bar();

...
y = static_cast<std::vector<int>&&>(x);


Now y contains what x did but we let x lose what it was holding in the process. That's ugly syntax, so the standard provides a function with much better syntax:
std::vector<int> x = foo();
std::vector<int> y = bar();

...
y = std::move(x);




More to come. In particular, auto_ptr is deprecated, long live unique_ptr, which is based on the above.

A good reference.
Tags: c++ cpp
  • Post a new comment

    Error

    default userpic

    Your IP address will be recorded  

  • 4 comments