
On Mon, Dec 03, 2007 at 03:24:33PM -0800, chun ping wang wrote:
hmm what do you mean? can you give a example.
template < class T, class U, template
class CONT void getKeys(const boost::unordered_map
& data, const CONT<T>::iterator);
There's no need to "templatize" the container. Demanding the iterator is typedef'ed in the container is a not needed and makes the code less generic. Rather, just accept all types that model the output iterator concept and you should be fine, like so (alt.1): template< typename MapType, typename OutputIterator > OutputIterator getKeys( MapType const& map, OutputIterator out ) { for( MapType::const_iterator it = map.begin(); it != map.end(); ++it ) { *out++ = it->first; } return out; } This probably works for any type that supports the typical iteration functions and uses std::pair<>s as iterator values, e.g. std::map<>, but I haven't compiled or tested the code. Returning the iterator is useful for the caller: it can immediate call the next function with the returned iterator without having to determine how many elements you've written. This is an example just to show you what I mean in my previous mail. It would be much better to write an iterator adapter (as suggested earlier), in which case you can write the above function as a simple std::copy expression (alt.2): out = std::copy( my_iterator_adapter( map.begin() ), my_iterator_adapter( map.end() ), out ); And... you can use all the other STL algorithms (e.g. find_if) directly on the keys of your map without copying them in a container. This is not possible using alt.1. Both of the above alternatives can be used with a function_output_iterator to create an ad hoc for-all-keys-do-the-following function: void acceptKey( Key const& key ) { /* ... */ } // using alt.1 map.getKeys( boost::make_function_output_iterator( acceptKey ) ); // using alt.2 std::copy( my_iterator_adapter( map.begin() ), my_iterator_adapter( map.end() ), boost::make_function_output_iterator( acceptKey ) ); Of couse, if you chose alternative 2 you can also use std::for_each, which is probably a lot clearer to other people reading your code. There are other uses as well, such as writing to an std::ostream, or whatever. The STL is quite flexible if you use the right concepts. Note that all these applications are not possible if you use an STL container to get the keys. N.