Re: How to pass the field name of a struct as a parameter?
mlimber =E5=86=99=E9=81=93=EF=BC=9A
Jellicle wrote:
mlimber =E5=86=99=E9=81=93=EF=BC=9A
Markus Schoder wrote:
Jellicle wrote:
But I cannot compile the codes successfully in Visual C++ 6.0.
You probably need a newer compiler.
Try this (I didn't test it, but it compiles :-) ). I think it should
work with VC++ 6, and it works with keys of different types and
different names:
#include <vector>
#include <cassert>
using namespace std;
template<class Iterator, typename key_type, typename T>
Iterator minfield(
Iterator start,
const Iterator &end,
key_type T::*p)
{
key_type acc = (*start).*p;
Iterator min_i(start);
++start;
while(start != end)
{
const key_type &r = (*start).*p;
if(r < acc)
{
acc = r;
min_i = start;
}
++start;
}
return min_i;
}
struct S1
{
typedef int key_type;
key_type key1;
S1( key_type key ) : key1(key) {}
};
struct S2
{
typedef double key_type;
key_type key2;
S2( key_type key ) : key2(key) {}
};
int main()
{
std::vector<S1> v1;
v1.push_back( S1(1) );
v1.push_back( S1(5) );
v1.push_back( S1(-10) );
v1.push_back( S1(3) );
vector<S1>::const_iterator m1 = minfield(
v1.begin(), v1.end(), &S1::key1 );
assert( m1->key1 == -10 );
std::vector<S2> v2;
v2.push_back( S2(1.1) );
v2.push_back( S2(5.1) );
v2.push_back( S2(-1.1) );
v2.push_back( S2(3.1) );
vector<S2>::const_iterator m2 = minfield(
v2.begin(), v2.end(), &S2::key2 );
assert( m2->key2 == -1.1 );
return 0;
}
Cheers! --M
Thank you, mlimber. I am really grateful for you kind help!
Yes, it works well in VC6 :)
However, my question is that the structs were defined by other people,
and were used
somewhere else. So I cannot redefine them.
There should be no need to alter the structs (I had initially added the
key_type to them but realized I didn't need to). If the structs looked
like this, it would work the same:
struct S1
{
int key1;
// ... whatever else
};
struct S2
{
double key2;
// ... whatever else
};
Yes! It works! Thank you:)
And do you think that at least I can save a little time/space if I use
a macro as this :-)
// for vector of struct
#define MINFIELD(vs,f) (minfield(vs.begin(), vs.end(), &f) -
vs.begin())
// for array of struct
#define MINFIELD2(as,size,f) (minfield(as, as+size, &f) - as)
I have test these as follows
#define MINFIELD(vs,f) (minfield(vs.begin(), vs.end(), &f) -
vs.begin())
#define MINFIELD2(as,size,f) (minfield(as, as+size, &f) - as)
main()
{
score_t scores[3]={100,93, 71, 70,59,83, 77,99,88};
int d2 = MINFIELD2(scores, 3, score_t::mathematics);
int d3 = MINFIELD2(scores, 3, score_t::mathematics) * 6;
int d4 = 8 * MINFIELD2(scores, 3, score_t::mathematics);
std::vector<goods_t> gg;
goods_t g;
g.price = 122.1; g.amount=100;
gg.push_back(g);
g.price = 322.2; g.amount=120;
gg.push_back(g);
g.price = 1012.4; g.amount=12;
gg.push_back(g);
g.price = 102.3; g.amount=110;
gg.push_back(g);
int i5 = MINFIELD(gg, goods_t::price);
int i6= 5*MINFIELD(gg, goods_t::price);
int i7 = MINFIELD(gg, goods_t::price) * 6;
return 0;
}
Cheers! --M