c++ - Template Class wrong copy constructor called -
solution
to avoid problem std::auto_ptr 1 can switch boost::shard_ptr or c++11 std::shared_ptr.
i error wrong copy constructor called in template class:
mpinetworkcode.hpp: error: no matching function call mpilib::mpinode<double>::mpinode(mpilib::mpinode<double>) mpinode.hpp: note: candidate is: mpilib::mpinode<double>::mpinode(mpilib::mpinode<double>&) here code lines result in error.
int mpinetwork<weightvalue>::addnode(const algorithminterface<weightvalue>& alg, nodetype nodetype) { mpinode<weightvalue> node = mpinode<weightvalue>(alg, nodetype, tempnodeid, _nodedistribution, _localnodes); _localnodes.insert(std::make_pair(tempnodeid, node)); } what wrong code, , why wrong copy constructor called? in previous version of class without templates worked fine.
here header of related classes. template implementation in header file.
here mpinetwork:
template <class weightvalue> class mpinetwork: private boost::noncopyable { public: explicit mpinetwork(); ~mpinetwork(); /** * adds new node network * @param alg algorithm of actual node * @param nodetype type of node * @return returns nodeid of generated node */ int addnode(const algorithminterface<weightvalue>& alg, nodetype nodetype); //lot of code }; and second mpinode, default copy constructor should called:
template <class weight> class mpinode { public: /** * constructor * @param algorithm algorithm algorithm node should contain * @param nodetype nodetype type of node * @param nodeid nodeid id of node * @param nodedistribution node distribution. * @param localnode local nodes of processor */ explicit mpinode(const algorithminterface<weight>& algorithm, nodetype nodetype, nodeid nodeid, const boost::shared_ptr<utilities::nodedistributioninterface>& nodedistribution, const std::map<nodeid, mpinode<weight> >& localnode); virtual ~mpinode(); time evolve(time time); void configuresimulationrun(const simulationrunparameter& simparam); void addprecursor(nodeid nodeid, const weight& weight); void addsuccessor(nodeid nodeid); nodestate getstate() const; void setstate(nodestate state); void receivedata(); void sendownstate(); private: void waitall(); std::vector<nodeid> _precursors; std::vector<weight> _weights; std::vector<nodeid> _successors; std::auto_ptr<algorithminterface<weight> > _algorithm; nodetype _nodetype; nodeid _nodeid; const std::map<nodeid, mpinode>& _reflocalnodes; boost::shared_ptr<utilities::nodedistributioninterface> _nodedistribution; nodestate _state; std::vector<nodestate> _precursorstates; std::vector<boost::mpi::request> _mpistatus; }; template<class weight> mpinode<weight>::mpinode(const algorithminterface<weight>& algorithm, nodetype nodetype, nodeid nodeid, const boost::shared_ptr<utilities::nodedistributioninterface>& nodedistribution, const std::map<nodeid, mpinode>& localnode) : _algorithm(algorithm.clone()), _nodetype(nodetype), _nodeid(nodeid), _nodedistribution( nodedistribution), _reflocalnodes(localnode) { }
your problem caused member:
std::auto_ptr<algorithminterface<weight> > _algorithm; std::auto_ptr's copy constructor doesn't copy, transfers ownership. because of takes non-const reference argument, not const reference.
this means when compiler comes generate copy constructor mpinode specialization cannot generate copy constructor takes const reference mpinode, can generate 1 takes non const reference.
in initialization, temporary mpinode<weightvalue> cannot bind non-const reference parameter generated copy constructor requires.
mpinode<weightvalue> node = mpinode<weightvalue>(alg, nodetype, tempnodeid, _nodedistribution, _localnodes); how fix depends on design. might supplying user-defined copy constructor takes const reference , clones _algorithm member correct approach.
Comments
Post a Comment