c++11 - How do I iterate over collections generically in C++? -


simply put, if have set , vector how create generic method can handle both params.

all want do, iterate on either types of collections. sounds should trivial i'm missing something.

void printmesomestrings(somebaseclass<string> strings) {   (auto& str : strings) {     cout << str << endl;   } } 

in c#, pass ienumerable or that. iterate on collection.

any general reading explaining answer appreciated.

the first option put code doing iterating in template. requires exposing implementation uses it, has disadvantages.

basically, take type c template parameter, write code in terms of type c.

template<typename c> void printmesomestrings(c&& strings) {   (auto const& str : strings) {     cout << str << endl;   } } 

if want able have strong barrier between interface , implementation, c++11 approach engage in type erasure on for-iterable container, , expose for-iterable container, how std::function works.

this trickier. find writing for_each function easier writing full blown iteration adapter. if want full blown container iteration type erasure object, start boost, or ask me below , might it.

the for_each adaptor easy, however.

#include <functional> #include <utility> #include <iterator> #include <memory>  template<typename t> struct for_each_helper_interface {   virtual ~for_each_helper_interface() {}   virtual void for_each( std::function< void(t) > const& ) = 0; }; template<typename c, typename t> struct for_each_helper:for_each_helper_interface<t> {   c& c;   for_each_helper( c& in ):c(in) {}   virtual void for_each( std::function< void(t) > const& f ) override final {     for( auto&& x:c ) {       f(x);     }   } }; template<typename t> struct for_each_adaptor {   std::unique_ptr<for_each_helper_interface<t>> pimpl;   void for_each( std::function< void(t) > const& f ) {     if (pimpl) {       pimpl->for_each(f);     }   }   template<typename c>   for_each_adaptor( c&& c ): pimpl( new for_each_helper<c, t>( std::forward<c>(c) ) ) {} }; 

which type-erase container of t (or type convertible t!) , expose for_each method lets iterate on contents of container. use this:

#include <set> #include <iostream> #include <vector> void print_stuff( for_each_adaptor<std::string const&> c ) {   c.for_each([&](std::string const&s){     std::cout << s << "\n";   }); } int main() {    std::set<std::string> s;    s.insert("hello");    s.insert("world");    print_stuff(s);    std::vector<std::string> v;    v.push_back("hola");    v.push_back("bola");    print_stuff(v);  } 

what going on here each type used construct our adaptor, build custom implementation of each. store pointer abstract base class of custom class, , redirect each calls it.

this means specializes std::begin or defines own begin need not related: create ad hoc relationships @ point of use instead.

live example: http://ideone.com/xoqbki


Comments

Popular posts from this blog

jquery - How can I dynamically add a browser tab? -

node.js - Getting the socket id,user id pair of a logged in user(s) -

keyboard - C++ GetAsyncKeyState alternative -