tags:

views:

42

answers:

3
+2  A: 

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++;
  }
// ...
Vijay Mathew
@vijay ohh.. yesterday also you gave me the answer. Yes i created vector for structure instances. But find_if gives me the first instance only, and one more thing => if input is : salary=9000, then it should give me a1, a3(first check for member name, next if member name is there - then value). Can you write a sample code for this.
jony
A: 
  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.
Space_C0wb0y
this empid is just for the testing purpose, and datatype may not be equal, if have 20 structures with 20 columns - how to use map??? There is no primary key like that. If i search for : deductions = 30 (from command prompt : no other information), then how to do?
jony
A: 

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...

Nim
yes... it solves the problem of generosity, but i really struck here "As to how to map "empid" to the real empid field in the structure emp", if i give input like this " emp, empid = 1" then how to map empid to emp.empid. thanks for the answer.
jony
This is handled by what I called "meta data" - I'll edit the answer above..
Nim
Also, if you need to parse "emp, empid=1", that is a different problem, I'm hoping you've worked out how to do that?? If not, look at string operations on any of the references out there (such as cplusplus.com)
Nim