C++ Reference to vector of derived types -


i have numerous objects implementing interface called exposescommands.

class exposescommands {     virtual bool get_command_results(std::string command, std::vector<std::string> &results) = 0; }; typedef std::unique_ptr<exposescommands> exposescommands_ptr; 

commands exposed via template class:

template <typename t> class exposedcommands : public exposescommands { private:     static std::map<const char*, std::string t::*, cmp_str> exposed_cmds;  public:     virtual bool get_command_results(std::string command, std::vector<std::string> &results); } 

now, trying add sub-commands. sub-commands link sub-objects implement commands. way add them so:

template <typename t> class exposedcommands : public exposescommands { private:     static std::map<const char*, std::string t::*, cmp_str> exposed_cmds;     static std::map<const char*, std::vector<exposescommands_ptr> t::*, cmp_str> exposed_sub_cmds;  public:     virtual bool get_command_results(std::string command, std::vector<std::string> &results) {         auto &it = exposed_cmds.find(command.c_str());         if (it != exposed_cmds.cend()) {             auto x = std::bind(it->second, std::placeholders::_1);             std::string data = x(*((t*)this));             if (data != "") {                 results.push_back(data);             }             return true;         }         // else check if in exposed_sub_cmds.             // if so, iterate through vector, call get_command_results             // on remainder of command name each sub object, adding             // result vector of results.             // return true         //         return false;     } } 

i have objects implementing interface (building of maps not shown here):

class objecta : public exposescommands<objecta> { public:     std::string cmd_x;  // command x     std::string cmd_y;  // command y } typedef std::unique_ptr<objecta> objecta_ptr;  class objectb { public:     std::string cmd_z;  // command z     std::vector<objecta_ptr> my_as;  // 'objecta' sub commands } 

unfortunately, doesn't work because can't assign &std::vector<objecta_ptr> std::vector<exposescommands_ptr> t::*.

is there way around this? or better approach problem?

to summarize problem: have base class , derived classes

class base { public:     virtual ~base(); }; class derived1 : public base; class derived2 : public base; 

you need store collection of pointers (for ownership management chose use std::unique_ptr, seems wise) derived1 objects in way can used code doesn't know derived1 exists, , wants use properties of base, not want lose property specific collection of base objects contains derived1 objects only. kind of type erasure, runtime behaciour of collection should not depend on whether stores base, derived1 or derived2 objects (or mixture of it, property gets erased), yet @ compile time, don't want write ugly downcasts (and want compiler verify downcast objects container statically know contain derived1 objects). aware if going store pointers derived1 in std::unique_ptr<base>, absolutely necessary base has virtual destructor.

i don't know ready-made solution off-hand (it couldn't find skimming on boost libraries tagged container, too), can show how reach goal yourself. need template, different compile-time types (just std::vector template), internally stores data in fixed type. this:

typedef std::unique_ptr<base> base_ptr; template <typename t> class basevector { public:     const std::vector<base_ptr> &         as_baseclass_vector() const     {         return backing_;     } private:     std::vector<base_ptr> backing_; }; 

note as_baseclass_vector return const reference raw vector, because result must not used insert objects of wrong type (e.g. pointers derived2 objects) commandvector instantiated derived1. half way go, other half sadly reimplementing standard library container concept on vector-wrapper, along this:

template<typename t> void commandvector::push_back(std::unique_ptr<t> obj) {     backing_.push_back(std::move(obj)); } 

or, more importantly , interestingly:

template<typename t> const t* basevector::operator[](size_t index) const {     return static_cast<t*>(backing_[index]); } 

note operator[] not return reference-to-unique_ptr, return reference unique_ptr<base>, because stored in backing vector. if created tempory unique_ptr t, have remove ownership vector - not want that! result has been declared const, because returns copy instead of usual reference, , modifying return value (which forbidden) not modify object in vector, opposed users expect. have reimplement other methods (iterators quite interesting, can based on boost::transform_iterator) if chose go route.


Comments

Popular posts from this blog

asp.net mvc - SSO between MVCForum and Umbraco7 -

Python Tkinter keyboard using bind -

ubuntu - Selenium Node Not Connecting to Hub, Not Opening Port -