c++ – structure member name – search – Education Career Blog

In the previous question, i made a big mess there. So i want to give it a new try.


struct emp
{
    int salary;
    string empid;
};
struct payroll
{
    int empid;
    int deductions;
};
    emp a1,a2, a3;  

    a1.salary = 9000;
    a1.empid = 1;

    a2.salary = 1000;
    a2.empid = 2;

    a3.salary = 9000;
    a3.empid = 3;

    payroll p1,p1,p3;   

    p1.empid = 1;
    p1.deductions = 10;

    p12.empid = 2;
    p2.deductions = 20;

    p3.empid = 3;
    p3.deductions = 30;

now, from the command prompt i have given like this

empid = 1;

then i need the answer that a1 and p1.
Here i need to check whether structures have the member name : empid – if true – then check for empid = 1.

How to do this in a generic way. I mean if i have 30 structures like this how to do. Give me any idea, if this is not possible, then how to do it using any other data structure.

,

There is no portable way to dynamically inspect the member variable name of a structure. If you don’t want to inspect the member variable name, use an std::vector to store the structure instances. Use std::find_if to search for a particular instance that satisfies a predicate. See this link for usage example of find_if. If you really want to check if a field named empid exist in the struct, use an std::map instead:

typedef std::map<std::string, int> emp;
typedef std::map<std::string, int> payroll;
typedef std::vector<emp> emp_list;
typedef std::vector<payroll> payroll_list;

emp_list emps;
emp a1;
a1"empid" = 1;
a1"salary" = 9000;
emps.push_back(a1);
// ...

payroll_list pays;
payroll p1;
p1"empid" = 1;
p1"deductions" = 10;
pays.push_back(p1);
// ...

// use an iterator over emps and pays to check for specific items
emp_list::const_iterator eit = emps.begin ();
emp_list::const_iterator eend = emps.end ();
while (eit != eend)
  {
    emp e = *eit;
    int eid = e"empid";
    if (eid == empid)
      {
        std::cout << e"salary" << '\n';
      }
    eit++;
  }
// ...

,

  1. You should use a consistent data type for empid across all structs.
  2. As @Vijay Mathew suggests, use a vector and then search. Alternatively you can use a map with empid as the key, this will give better performance for large numbers of entries.

,

If I understand your question correctly, if you have 30 structures (tables) in your “database”, you want to find all structures that have “empid” as a column (i.e. member of structure)? In C++ I’m not aware of a mechanism to test whether a structure has a particular member by name, at least not a name provided at runtime. You need to store this in some form of “meta data” – e.g. maps with string keys that lists a set of structures for example (or encoded in logic with string comparisons etc.)…

Here is a rough sketch…

A “table” class typed on the row type (i.e. structure)

class table
{
  // some virtual methods common to all classes..
};

template <typename _Row>
class data_table : public table
{
  // methods

  // real data
  std::vector<_Row> data;
};

then you need a database class to hold all the tables..

class database
{
  // methods
  std::map<int, boost::shared_ptr<table> > tables; // here int is for a unique id for table
};

Now you have a collection of tables, where each table is a set of rows (structures). You then need to define some metadata for the database, i.e. map columns to tables etc..

std::multimap<std::string, boost::shared_ptr<table> > columns;

This you have to populate using your knowledge of the structures, for example, this map may contain, for your code above:

columns"empid" = id of table<emp>;
columns"empid" = id of table<payroll>;

etc.

Now, you can pass a “query” to your “database” class, where you say something like, “empid” = 1, and then you lookup in the columns map and find all instances of tables, and then each table you can query with “empid” = 1. As to how to map “empid” to the real empid field in the structure emp, you have to embed that logic into methods in the emp structure which table<emp> can delegate to (or if you can think of a smart way of storing references to members… )

It’s only a suggestion…

Or alternatively, consider using one of the many databases out there which will support real queries, and run either as standalone or embedded!

Edit:

struct emp
{
  int empid;
  string empname;

  template <typename T>
  bool matches(const string& field_name, const T& value)
  {
    if (field_name == "empid")
      return empid == value;
    else if (field_name == "empname")
      return empname == value;
    // etc
    return false;
  }

};

So the “metadata” is encoded in the logic for test, you pass in a string field name, and then depending on what it is, you compare the appropriate value… This isn’t very efficient, but it works…

Leave a Comment