0

I am trying to use boost factory and I am experiencing the following problem. All I am trying to do is having a bunch of derived classes to have a mechanism that will be initializing the derived class that is matched with a corresponding string. To begin with I have the following base class called name NetWorkBlock,

NetWorkBlock.h

class NetWorkBlock {

protected:

typedef boost::function<NetWorkBlock * ()> NetWorkFactory;
//definition of the function that will be used for the factory

public:

NetWorkBlock();
virtual ~NetWorkBlock();

//some basic functionalities that not related to the factory 
  and thus not mentioned

static std::map<std::string,NetWorkBlock::NetWorkFactory>& f_factory();
//static function that initializes and returns the map
};

NetWorkBlock.cpp

NetWorkBlock::NetWorkBlock() {
} //empty constructor

NetWorkBlock::~NetWorkBlock() {
} //empty deconstructor

std::map<std::string,NetWorkBlock::NetWorkFactory>& NetWorkBlock::f_factory()
{
 static std::map<std::string,NetWorkBlock::NetWorkFactory>* ans =
 new std::map<std::string,NetWorkBlock::NetWorkFactory>();
 return *ans;
} //initialization of map

Moving on here is how I define things in the the derived class BusNetworkBlock (note ofcourse there are more derived classes expected to be defined later, but in the current moment I work with a single derived class to manage to have things working):

BusNetworkBlock.h

class BusNetworkBlock {

public:

BusNetworkBlock();
virtual ~BusNetworkBlock();

//some basic functionalities that not related to the factory 
  and thus not mentioned

private:

/* Very small, "fake" class _initializer. Its only meaning is to define a
   static member _init that is initialized at the very beginning of the
   main(). Hence the constructor is called, and the constructor registers
   the BusNetworkBlock class into the (static) NetWorkBlock::f_factory. */

static class _init {
     public:
      _init() {
           NetWorkBlock::f_factory()["LoadCurve"] = boost::factory<BusNetworkBlock *>();
      }
     }_initializer;

};

BusNetworkBlock.cpp

BusNetworkBlock::BusNetworkBlock() {
} //empty constructor

BusNetworkBlock::~BusNetworkBlock() {
} //empty deconstructor

/* The definition of the bodies of the funcionalities of the class that are not mentioned here since they are not connected with the factory */

BusNetworkBlock::_init BusNetworkBlock::_initializer;

/* Ensure that the static member _initializer is initialized, so that
   BusNetworkBlock is registered into NetWorkBlock::f_factory. */

Now in an other separate class under the name UCBlock I try to use the factory in order to initialize properly the derived NetworkBlock class based on a string I receive in the following way:

UCBlock.h

 class UCBlock {

  public:

    UCBlock(std::istream& inStream); //the received instream 
    virtual ~UCBlock();

//some basic functionalities that not related to the factory 
  and thus not mentioned

   NetWorkBlock * Network; /*defining a pointer of the base class NetWorkBlock
          that want to initialize properly via the factory */

};

UCBlock.cpp

 UCBlock::UCBlock( std::istream& inStream ) {

inStream >> network; //setting the string of network the corresponding factory
Network = NetWorkBlock::f_factory()[network](); // set the corresponding object via factory **here is where the problem arises**
}

And the problem arises when I try to use the factory to proper initialize the derived class of NetWorkBlock. I receive the following error:

 terminate called after throwing an instance of 'boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<boost::bad_function_call> >'
 what():  call to empty boost::function
 Aborted (core dumped)

Now I have ofcoruse tried to check this thing online but didn't manage to come up with a solution and that's why I would really appreciate any kind of help here, since I am really stacked here. (Note also that I checked that the string I receive is correct and matches with "LoadCurve").

user3111197
  • 83
  • 2
  • 11

0 Answers0