Wednesday 27 November 2013

Some STL functions are Simpler Than You Might Think

The STL functions generate and generate_n are quite useful, but when I first used them I thought I must be missing something. It turns out though that these functions, like many in the standard library, are really simple.

The first time I used generate_n was to initialise a vector. I looked at the documentation and quickly found how to achieve this, but sub-consciously I assumed I was only scratching the surface of what it could do. I probably thought that way about all STL functions, and in many cases I would have been right. For an example try stepping into the line:

std::cout << "Hello, world\n";

If you understand everything that happens in the above line of code you're probably someone who gets paid to implement the standard library. The fact that the operator<< is from the std namespace should have you scratching your head until you've read about Name Lookup, more specifically Koenig Lookup.

However, with generate_n, things are much more straight forward. In fact, generate_n is most easily understood, and in my case demystified, by looking at the implementation. Here's the crux of the function from VC++ 2012:

template<class _OutIt,
  class _Diff,
  class _Fn0> inline
  _OutIt _Generate_n(_OutIt _Dest, _Diff _Count, _Fn0 _Func)
  {
  for (; 0 < _Count; --_Count, ++_Dest)
    *_Dest = _Func();
  return (_Dest);
  }


That's as difficult as it gets

The above code is probably as easy to understand as any documentation on generate_n. But, more importantly, when you get this, you understand the function completely. There's nothing else to it, there's no smoke nor mirrors, no __asm__, and it doesn't link to any binaries to do the real work. It's just a small bit of C++ code.

The generate function is similar except it expects two input iterators and the for loop looks like:

for (; _First != _Last; ++_First)

If you look at the standard itself this shouldn't come as a surprise. After the function declaration there are just seven lines detailing what both generate and generate_n need to conform to. Many other useful STL functions have a similar level of complexity.

This won't come as a surprise to everyone, but for me it was encouraging to know that although I may never understand the language completely, there are many parts that I can get to the bottom of quite easily. It's also encouraged me to step into standard library functions as a first port of call, and shown me a less intimidating side of the C++ Standard itself. That said, I think I need some more experience before I'm ready to tackle:

std::cout << "Hello, world\n";

No comments: