You could do one of four things:
1) Use the upcoming auto keyword, as already answered.
2) Give the container typedef a generic name so that you can change its type without wanting to rewrite general usages of it.
typedef std::vector<config_value_ptr> config_value_container;
config_value_container config;
config_value_container::iterator it = config.begin();
3) If you want the container typedef's name to stay specific, then you could make an iterator typedef.
typedef std::vector<config_value_ptr> config_value_vec;
typedef config_value_vec::iterator config_value_container_iterator;
config_value_vec config;
config_value_container_iterator it = config.begin();
Of course, if you start needing different types of iterators for the container (const vs non-const, backward vs forward, etc) then you may end up with several iterator typedefs.
4) Don't bother with it, because container types can have fundamental differences that you may not be able to resolve with simple typedefs. For instance, std::sort can be used with std::vector but not std::list. Depending on what your code does (or may need to do in the future), trying to keep it truly type-agnostic may take more time than it's worth. But you'll have to evaluate that yourself.