473,662 Members | 2,375 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

How to pass the field name of a struct as a parameter?


There are some sturct arrays (or struct vectors), such as:

struct S1_t
{
double keyField ;

..// other fields
}

S1_t s1[100];
std::vector<S1_ t> vecS1;

I need to find the index of the item in array "s1" or vector "vecS1"
which
has the minimal value in field "keyField".

Some codes could be:
//----------------------------------------------

double minvalue = s1[0];
for (int i=0; i< 100; i++ ) // for (int i=0; i< vecS1.size(); i++)
....
{
if (s1[i].keyField < minvalue )
{
minvalue =s1[i].keyField;
index = i;
}
}
//----------------------------------------------

However, since there are many such arrays(vectors) with different
struct type
(so, with different "field" name)

How can I define a function (or MACRO?) to get the index
of the minumal item (by comparing the the value of a key field)?

such as MIN(struct_arra y_variable, field_name)

e.g.

index = MIN(s1, keyField);

to get the index of array "s1" with a minimal value of "keyField".

And ,

index = MIN(s2,f2) get that of "s2" (defined as follows:)

struct s2_t
{
int f2;

// other fields

}

s2_t s2[100]


A similar function is FIND(struct_arr ay, field, value)
to find the index from array "struct_arr ay", where

struct_array[index].field == value;

I think that the sticking point is that how to pass the field name
as a parameter? isn't it?

Could anyone help me?

Thank you very much!

Jun 28 '06 #1
17 3400
Jellicle wrote:
There are some sturct arrays (or struct vectors), such as:

struct S1_t
{
double keyField ;

..// other fields
}

S1_t s1[100];
std::vector<S1_ t> vecS1;

I need to find the index of the item in array "s1" or vector "vecS1"
which
has the minimal value in field "keyField".

Some codes could be:
//----------------------------------------------

double minvalue = s1[0];
You mean

double minvalue = s1[0].keyField;

??
for (int i=0; i< 100; i++ ) // for (int i=0; i< vecS1.size(); i++)
You mean

for (int i=1; i< ...

??
...
{
if (s1[i].keyField < minvalue )
{
minvalue =s1[i].keyField;
index = i;
}
}
//----------------------------------------------

However, since there are many such arrays(vectors) with different
struct type
(so, with different "field" name)

How can I define a function (or MACRO?) to get the index
of the minumal item (by comparing the the value of a key field)?

such as MIN(struct_arra y_variable, field_name)

e.g.

index = MIN(s1, keyField);

to get the index of array "s1" with a minimal value of "keyField".

And ,

index = MIN(s2,f2) get that of "s2" (defined as follows:)

struct s2_t
{
int f2;

// other fields

}

s2_t s2[100]


A similar function is FIND(struct_arr ay, field, value)
to find the index from array "struct_arr ay", where

struct_array[index].field == value;

I think that the sticking point is that how to pass the field name
as a parameter? isn't it?


No, it isn't. The sticking point is to learn about pointers to
members and how they are used.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Jun 28 '06 #2
you can get the offset of a field f in a struct s using the following
well-known trick:

#define OFFSET(s,f) &((struct s *) 0)->f

Once you have the offset, it becomes straightforward to solve your problem.

-Shimin

Jellicle wrote:
There are some sturct arrays (or struct vectors), such as:

struct S1_t
{
double keyField ;

..// other fields
}

S1_t s1[100];
std::vector<S1_ t> vecS1;

I need to find the index of the item in array "s1" or vector "vecS1"
which
has the minimal value in field "keyField".

Some codes could be:
//----------------------------------------------

double minvalue = s1[0];
for (int i=0; i< 100; i++ ) // for (int i=0; i< vecS1.size(); i++)
...
{
if (s1[i].keyField < minvalue )
{
minvalue =s1[i].keyField;
index = i;
}
}
//----------------------------------------------

However, since there are many such arrays(vectors) with different
struct type
(so, with different "field" name)

How can I define a function (or MACRO?) to get the index
of the minumal item (by comparing the the value of a key field)?

such as MIN(struct_arra y_variable, field_name)

e.g.

index = MIN(s1, keyField);

to get the index of array "s1" with a minimal value of "keyField".

And ,

index = MIN(s2,f2) get that of "s2" (defined as follows:)

struct s2_t
{
int f2;

// other fields

}

s2_t s2[100]


A similar function is FIND(struct_arr ay, field, value)
to find the index from array "struct_arr ay", where

struct_array[index].field == value;

I think that the sticking point is that how to pass the field name
as a parameter? isn't it?

Could anyone help me?

Thank you very much!

Jun 28 '06 #3
Victor Bazarov wrote:
Jellicle wrote:

Some codes could be:
//----------------------------------------------

double minvalue = s1[0];


You mean

double minvalue = s1[0].keyField;

??
for (int i=0; i< 100; i++ ) // for (int i=0; i< vecS1.size(); i++)


You mean

for (int i=1; i< ...

??


You are right exactly :-).
(and I should check if vecS1[0] exists in a vector :-) )

But what I puzzled is that how to handle the various types of
structs and fields in different arrays or vectors.

Jun 28 '06 #4
Shimin wrote:
you can get the offset of a field f in a struct s using the following
well-known trick:

Please don't top-post. See item four in the FAQ below:

<http://www.parashift.c om/c++-faq-lite/how-to-post.html#faq-5.4>


Brian

Jun 28 '06 #5
Shimin wrote:
you can get the offset of a field f in a struct s using the following
well-known trick:

#define OFFSET(s,f) &((struct s *) 0)->f

Once you have the offset, it becomes straightforward to solve your problem.

-Shimin


First, don't top-post. It is considered rude. Second, don't use this
trick unless you must. (Generally, if you must, it means your design is
flawed.)

A better solution would use a function to extract the proper key.
Something like:

struct S1 { int key1; /*...*/ };
struct S2 { int key2; /*...*/ };

int GetKey( const S1& s ) { return s.key1; }
int GetKey( const S2& s ) { return s.key2; }

template<class T>
int MinKey( const vector<T>& v )
{
if( v.size() == 0 ) return -1;
int min = GetKey( v[0] );
for( vector<T>::cons t_iterator i = v.begin()+1; i != v.end(); ++i )
{
if( GetKey( *i ) < min ) min = GetKey( *i );
}
return min;
}

If the keys are also different types, you could still do it, but it
would have to be a little fancier.

Cheers! --M

Jun 28 '06 #6

Shimin 写道:
you can get the offset of a field f in a struct s using the following
well-known trick:

#define OFFSET(s,f) &((struct s *) 0)->f

Once you have the offset, it becomes straightforward to solve your problem.

-Shimin

Thank you!

Would you explain it in detail?
1)how to implement something like :
if (s1[i].keyField < minvalue )

2) Is it possible to return a value, so
I can write a compact and beautiful statement in my codes:

index = MIN(s1, field);

But I am afrad that a macro can not return a value.

Jun 28 '06 #7
Jellicle wrote:
There are some sturct arrays (or struct vectors), such as:

struct S1_t
{
double keyField ;

..// other fields
}

S1_t s1[100];
std::vector<S1_ t> vecS1;

I need to find the index of the item in array "s1" or vector "vecS1"
which
has the minimal value in field "keyField".

Some codes could be:
//----------------------------------------------

double minvalue = s1[0];
for (int i=0; i< 100; i++ ) // for (int i=0; i< vecS1.size(); i++)
...
{
if (s1[i].keyField < minvalue )
{
minvalue =s1[i].keyField;
index = i;
}
}
//----------------------------------------------

However, since there are many such arrays(vectors) with different
struct type
(so, with different "field" name)

How can I define a function (or MACRO?) to get the index
of the minumal item (by comparing the the value of a key field)?

such as MIN(struct_arra y_variable, field_name)

e.g.

index = MIN(s1, keyField);

to get the index of array "s1" with a minimal value of "keyField".


A STL style solution using iterators would be:

#include <iterator>

template<class Iterator, typename T> Iterator minfield(Iterat or start,
const Iterator &end, T std::iterator_t raits<Iterator> ::value_type::* p)
{
T acc = (*start).*p;
Iterator min_i(start);
++start;
while(start != end)
{
const T &r = (*start).*p;
if(r < acc)
{
acc = r;
min_i = start;
}
++start;
}
return min_i;
}

Usage would be:

index = minfield(s1, s1 + 100, &S1_t::keyfield ) - s1;

or

index = minfield(vecS1. begin(), vecS1.end(), &S1_t::keyfield ) -
vecS1.begin();

Note that the function assumes that there is at least one value in the range
[start, end).

Jun 29 '06 #8
Jellicle wrote:
Shimin 写道:
you can get the offset of a field f in a struct s using the following
well-known trick:

#define OFFSET(s,f) &((struct s *) 0)->f

Once you have the offset, it becomes straightforward to solve your problem.

-Shimin

Thank you!

Would you explain it in detail?


To repeat from my post above, this trick should be avoided. See my post
and Markus Schoder's for two better options.
1)how to implement something like :
if (s1[i].keyField < minvalue )

2) Is it possible to return a value, so
I can write a compact and beautiful statement in my codes:

index = MIN(s1, field);

But I am afrad that a macro can not return a value.


Technically, a macro doesn't return anything. Macros are not functions
(despite the similar looking syntax); they are text substitutions. If
the text you substitute evaluates to a value, then it can be assigned
to some variable like you want to here. If it does not, then it cannot
be. For instance:

#define A 42
#define B { cout << "Hello"; }

int main()
{
int val1 = A; // Ok: becomes "int val1 = 42;"
int val2 = B; // Error: becomes "int val2 = { cout << "Hello"; };"
}

However, macros should be avoided when possible. See this FAQ and its
references for reasons why:

http://www.parashift.com/c++-faq-lit...s.html#faq-9.5

Cheers! --M

Jun 29 '06 #9

Markus Schoder wrote:


A STL style solution using iterators would be:

#include <iterator>

template<class Iterator, typename T> Iterator minfield(Iterat or start,
const Iterator &end, T std::iterator_t raits<Iterator> ::value_type::* p)
{
T acc = (*start).*p;
Iterator min_i(start);
++start;
while(start != end)
{
const T &r = (*start).*p;
if(r < acc)
{
acc = r;
min_i = start;
}
++start;
}
return min_i;
}

Usage would be:

index = minfield(s1, s1 + 100, &S1_t::keyfield ) - s1;

or

index = minfield(vecS1. begin(), vecS1.end(), &S1_t::keyfield ) -
vecS1.begin();

Note that the function assumes that there is at least one value in the range
[start, end).

Thank you and everyone!

But I cannot compile the codes successfully in Visual C++ 6.0.
It said that
"error C2653: 'value_type' : is not a class or namespace name"
on this line:
const Iterator &end, T
std::iterator_t raits<Iterator> ::value_type::* p)

if I remove "::" between "value_type " and "*p", it says:
"error C2143: syntax error : missing ',' before '*' "

Since I don't understand this code line exactly, I don't know how to
correct it.

Would you help me?

Thank you!

Jun 29 '06 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

110
9899
by: Mr A | last post by:
Hi! I've been thinking about passing parameteras using references instead of pointers in order to emphasize that the parameter must be an object. Exemple: void func(Objec& object); //object must be an object instead of
2
23968
by: Tony Johansson | last post by:
Hello! I use method forName and newInstance in class Class like this instance = (GameFactory)(Class.forName(name).newInstance() ); Now to my question: Assume that name is GameFactory then I want to pass a parameter to the GameFactory constructor like this instance = (GameFactory)(Class.forName(name).newInstance(field) ); Here I pass parameter field which is an int but when I do so I get compile
5
13214
by: Don Seckler | last post by:
I have an update query that runs when a report closes. I have several reports that will need to run the update query with diferent criteria. I'd like to simply make the criteria change in the report vba instead of making different queries. Here's my query sql: UPDATE Draw SET Draw.Billed = Yes WHERE (((Draw.Billed)=No) AND ((Draw.WholesalerName)="Hudson"));
6
5552
by: yezi | last post by:
Hi: How to code for operation between 2 structures? The structure's defination is : struct sockaddr_in my_addr; I need call a subfunction and pass the value in my_addr to the subfuncition , which same structure but different name?
3
1800
by: Brad McMillan | last post by:
Hi: I have MS C# 2005 Express Edition and I'm trying to pass a string to a new form in my project. First I created the form, Customer, with a textbox, "textBox1", and declared a string "name": namespace myProject {
3
2134
by: Ronald S. Cook | last post by:
I want to something as simple as: UserControl uctTemp; But the type will be passed in to the function (which will be an existing user control like "uctMyUserControl1") So, how can I pass in the string "uctMyUserControl1" and then somehow dim an instance of it?
12
3838
by: Fred | last post by:
Is it possible to create a function which will take any number of structures as an argument? For example, what if I wanted depending on the circumstances to pass a structure named astruct, or bstruct, or cstruct, to the function? Sort of like this: myfunc(char * str, struct astruct *as)
7
7022
by: p.lavarre | last post by:
How do I vary the byte offset of a field of a ctypes.Structure? How do I "use the dynamic nature of Python, and (re-)define the data type after the required size is already known, on a case by case basis"? \\\ For example, suppose sometimes I receive the value '\x03hi' + \x04bye' for the struct:
4
6679
by: S. | last post by:
Hi all, I have the requirement that I must pass-by-reference to my function addStudent() and getAge() functions where my getAge() function is within the addStudent() function. I am able to pass-by-reference to the first function, addStudent() but then I am confused as to how I am suppose to pass the pointer of 'student' from within the addStudent() function to the getAge() function that is nested within the addStudent() function.
0
8432
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, well explore What is ONU, What Is Router, ONU & Routers main usage, and What is the difference between ONU and Router. Lets take a closer look ! Part I. Meaning of...
0
8343
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
8856
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
1
8545
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
7365
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development projectplanning, coding, testing, and deploymentwithout human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
6185
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupr who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
1
2762
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
1992
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
2
1747
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.