structure member name - search
In the previous question, i made a big mess there. So i want to give it a new try.
struct emp
{
int开发者_StackOverflow 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++;
}
// ...
- You should use a consistent data type for
empid
across allstruct
s. - As @Vijay Mathew suggests, use a
vector
and then search. Alternatively you can use amap
withempid
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...
精彩评论