Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Access function pointers outside of the instance

I have a class as outlined below:

class InputReader 
{  
public:
  typedef void (*handler)(std::string, int);
  static void errorHandler(std::string error, int severity); //Supplies a default error handler
  static void warningHandler(std::string error, int severity); //Supplies a default warning handler
  handler errorH;
  handler warningH;

  InputReader(std::string pwd = "", handler eHandler = errorHandler, handler wHandler = warningHandler);

  bool readFile(std::string filename);
  std::vector<first> mesh;
  //other irrelevant objects that need to be read into
};

first is a struct:

struct first
{
  std::string filename;
  double scale;
};

With Mooing Duck's help I have:

std::istream& operator>>(std::istream& file, first& obj) 
{
  std::string symbol;
  while(file >> symbol) 
  {
    if (symbol[0] == '#') 
    {
      std::getline(file, symbol);
    } 
    else if (symbol == FIRSTTAGEND) 
    {
      break;
    }
    else if (symbol == FILEPATH) 
    {
      if (!(file >> '=' >> obj.filename))
        std::cerr << symbol << " is incorrectly formatted"; //This needs to use errorH
    } 
    else if (symbol == SCALE) 
    {
      if (! (file >> '=' >> obj.scale) )
        std::cerr << symbol << " is incorrectly formatted"; //This needs to use errorH
    } 
    else 
    { //not a member: failure
      std::cerr << symbol << " is not a member of first";
      file.setstate(file.rdstate() | std::ios::badbit);
      break;
    }
  }
  return file;
}

std::istream& operator>>(std::istream& file, InputReader& obj) 
{
  std::string symbol;
  while(file >> symbol) 
  {
    if (symbol[0] == '#') 
    {
      std::getline(file, symbol);
    } 
    else if (symbol == FIRSTTAGBEG) 
    {
      first t;
      if (file >> t)
        obj.mesh.push_back(t);
    } 
    else 
    {
      obj.errorH(symbol + " is not a member of the input reader.", 1);
      file.setstate(file.rdstate() | std::ios::badbit);
    }
  }
  return file;
}

bool InputReader::readFile(std::string filename)
{
  std::ifstream infile;
  infile.open(filename.c_str());
  infile >> *this;
  return true;
}

errorH gets set upon construction of the InputReader object. It can be provided by the user of the class, otherwise, it uses the default ones I provide. The only problem is that I can't access errorH when first is being read into. How can I solve this?

Problem constraints: External libraries are not allowed. C++11/C++OX is not allowed.

like image 569
Drise Avatar asked Jan 01 '26 01:01

Drise


1 Answers

You naturally have few options:

  1. Do not use >> operator and create a function that does the same but accepts three arguments - an input stream, a first object and an input reader object.
  2. Define operator >> that accepts a tuple of first and InputReader as a second argument (i.e. a pair of pointers). For example: std::istream& operator>>(std::istream& file, std::pair<first *, InputReader *> & obj).

You can extend this list indefinitely as long as you have a good imagination.

Hope it helps.

UPDATE:

Here goes some simple example:

#include <string>
#include <vector>
#include <fstream>
#include <iostream>

struct first {
    std::string filename;
    double scale;
};

class InputReader {
  public:
    typedef void (*handler)(const std::string &, int);

    InputReader(const std::string & pwd = std::string(),
                handler eHandler = errorHandler,
                handler wHandler = warningHandler);

    bool readFile(const std::string & filename);

    static void errorHandler(const std::string & error, int severity);
    static void warningHandler(const std::string & error, int severity);

    handler errorH;
    handler warningH;
    first firstobj;
    std::vector<first> mesh;
};

std::istream & operator >> (std::istream & file,
                            std::pair<first, InputReader *> & obj)
{
    std::string symbol;
    while (file >> symbol) {
        if (symbol[0] == '#') {
            std::getline(file, symbol);
        } else if (symbol == "FIRSTTAGEND") {
            break;
        } else if (symbol == "FILEPATH") {
            if (!(file >> obj.first.filename))
                obj.second->errorHandler(symbol + " is incorrectly formatted",
                                         1);
        } else if (symbol == "SCALE") {
            if (!(file >> obj.first.scale))
                obj.second->errorHandler(symbol + " is incorrectly formatted",
                                         1);
        } else { //not a member: failure
            std::cerr << symbol << " is not a member of first";
            file.setstate(file.rdstate() | std::ios::badbit);
            break;
        }
    }
    return file;
}

std::istream & operator>>(std::istream & file, InputReader & obj)
{
    std::string symbol;

    while (file >> symbol) {
        if (symbol[0] == '#') {
            std::getline(file, symbol);
        } else if (symbol == "FIRSTTAGBEG") {
            std::pair<first, InputReader *> t(first(), &obj);
            if (file >> t)
                obj.mesh.push_back(t.first);
        } else {
            obj.errorH(symbol + " is not a member of the input reader.", 1);
            file.setstate(file.rdstate() | std::ios::badbit);
        }
    }
    return file;
}

bool InputReader::readFile(const std::string & filename)
{
    std::ifstream infile;
    infile.open(filename.c_str());
    infile >> *this;
    return true;
}

Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!