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++;
}
// ...
,
,
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…