First, you don't need to use what you don't want.
Second, it's open, so you can enlist and have a say.
This is unlike proprietary systems, where you don't have a say, whatsoever (although, you can make suggestions).
Imagine a search class.
Iterators are used to iterate search results.
Each time you increment the iterator, it could search the next search result on-demand. It saves valuable execution time to find all results, and it makes things transparent to the user.
It works the way it is supposed you, and fast, yet with things going on behind the scenes with the help of an iterator.
Or another example. What is testing the iterator is boolean fashion like:
Returns false if it's beyond the range of what it is iterating (ie, found the last search result)?Code:if (it)
These are small examples of what generalization of iterators can do.
As for what smart pointers are... basically, they remove the burden of deallocation from the programmer.
boost::shared_ptr will keep a reference count to an object, so each time another part of the program keeps a reference (so to speak) to the allocated object, the count increases. When the references go down, so does the count, until it reaches 0, when it finally releases the allocated object.
This is basically done so that everytime a new boost::shared_ptr is created and assigned another boost::shared_ptr, the count increments. And everytime one of those objects go out of scope, the count decrements.
boost::shared_ptr is the most useful and popular smart pointer in the library and comes in handy pretty much all the time. boost::shared_ptr is also available in TR1: std::tr1::shared_ptr.
There are other smart pointers to solve other problems.
For example std::tr1::weak_ptr and std::auto_ptr.