I have a container that I wish to allow the user to specify a custom
comparison method very similar to std::less. However, I want it to
function more like memcmp (returning -1 0 1), and I want to be able to
vary the fields that are compared. The example below shows how I'd
like it to fit together.
struct fields
{
fields( int f1, int f2, int f3 ){ m_f[0] = f1; m_f[1] = f2; m_f[2]
= f3; }
int m_f[3];
};
template< typename T >
class Foo
{
public:
Foo( const T & t ) : m_t( t ){ }
int dosomething( const T & t )
{
// error: want to compare t by any of the 3 fields. the method
// passed in should handle which fields are compared.
if( t < m_t ) return -1;
else if( t > m_t ) return 1;
else return 0;
}
protected:
const T m_t;
};
int main(int argc, char* argv[])
{
Foo< fields > foo( fields( 3, 2, 1 ) );
foo.dosomething( fields( 1, 2, 3 ) );
return 0;
} 4 1528
"titancipher" <ja***********@gmail.com> wrote in message
news:11*********************@z14g2000cwz.googlegro ups.com... I have a container that I wish to allow the user to specify a custom comparison method very similar to std::less. However, I want it to function more like memcmp (returning -1 0 1), and I want to be able to vary the fields that are compared. The example below shows how I'd like it to fit together.
struct fields { fields( int f1, int f2, int f3 ){ m_f[0] = f1; m_f[1] = f2; m_f[2] = f3; } int m_f[3]; };
If you need to compare objects of type 'fields' define comparison operators
for this type:
bool operator < (const fields& l, const fields& r)
{
/* return whatever logic comes here; */
}
bool operator > (const fields& l, const fields& r)
{
/* return whatever logic comes here; */
}
Regards,
Janusz
titancipher wrote: I have a container that I wish to allow the user to specify a custom comparison method very similar to std::less. However, I want it to function more like memcmp (returning -1 0 1), and I want to be able to vary the fields that are compared. The example below shows how I'd like it to fit together.
struct fields { fields( int f1, int f2, int f3 ){ m_f[0] = f1; m_f[1] = f2; m_f[2] = f3; } int m_f[3]; };
template< typename T > class Foo { public: Foo( const T & t ) : m_t( t ){ } int dosomething( const T & t ) { // error: want to compare t by any of the 3 fields. the method // passed in should handle which fields are compared. if( t < m_t ) return -1; else if( t > m_t ) return 1; else return 0; } protected: const T m_t; };
int main(int argc, char* argv[]) { Foo< fields > foo( fields( 3, 2, 1 ) ); foo.dosomething( fields( 1, 2, 3 ) ); return 0; }
You want to make your "dosomething" function a member template. For
example:
template <class Compare>
int dosomething( const T & t, const Compare & comp)
{
int result = comp(t, m_t) ;
if (result == 1)
std::cout << "greater" << std::endl ;
else if (result == -1)
std::cout << "less" << std::endl ;
else
std::cout << "equal" << std::endl ;
}
Then your user defined comparison objects will look something like this.
class compare_field
{
unsigned n ; // field to compare
public :
compare_field(unsigned n) : n(n) {}
int operator()(const fields &f1, const fields &f2) const
{
if (f1.m_f[n] < f2.m_f[n])
return -1 ;
else if (f1.m_f[n] > f2.m_f[n])
return 1 ;
else
return 0 ;
}
} ;
You may then call dosomething in a manner similar to this :
Foo< fields > foo( fields( 3, 2, 1 ) );
foo.dosomething( fields( 1, 2, 3 ), compare_field(0) );
foo.dosomething( fields( 1, 2, 3 ), compare_field(1) );
foo.dosomething( fields( 1, 2, 3 ), compare_field(2) );
-Alan
Hi Alan,
Thanks, what you describe would work. However, I was looking to
provide a more STL-like method. If you look at std::map, std::set,
etc., the method std::less is used as a default argument in the
template specification. What you propose would require passing a
compare_field(0) for each insert (i.e. 'dosomething').
I've done a little more thinking about it, and have a solution. I'll
post it. First, I create a class much like std::less called compare:
template< typename T >
class compare : public std::binary_function< T, T, int >
{
public:
compare(){ }
public:
bool operator()( const T & lhs, const T & rhs ) const
{
if( lhs < rhs ) return -1;
else if( lhs < rhs ) return 1;
else return 0;
}
};
Then, I change Foo to use the binary function 'compare' by default:
template< typename T, class C = compare< T > >
class Foo
{
public:
Foo( const T & t ) : m_t( t ){ }
int foocmp( const T & t )
{
int c = compare( t, m_t );
if( c < 0 ) return -1;
else if( c > 0 ) return 1;
else return 0;
}
protected:
const T m_t;
const C compare;
};
Then, because the default compare is not adequate to compare my fields
class (it does not compare individual fields), I write a custom compare
per-field. Field 0 compare is below:
class cmp_field_0 : public std::binary_function< fields, fields, int >
{
public:
cmp_field_0() : m_n( 0 ) { }
public:
int operator()( const fields & lhs, const fields & rhs ) const
{
if( lhs.m_f[ m_n ] < rhs.m_f[ m_n ] ) return -1;
else if( lhs.m_f[ m_n ] < rhs.m_f[ m_n ] ) return 1;
else return 0;
}
private:
int m_n;
};
The usage is now:
Foo< fields, cmp_field_0 > foo( fields( 3, 2, 1 ) );
foo.dosomething( fields( 1, 2, 3 ) );
However, I would have to create a cmp_field_1, cmp_field_2, etc., and
that's that's still not great. I can then change the cmp_field to
include another template argument to indicate the field to test:
template< int F >
class cmp_field : public std::binary_function< fields, fields, int >
{
public:
cmp_field() : m_n( F ) { }
public:
int operator()( const fields & lhs, const fields & rhs ) const
{
if( lhs.m_f[ m_n ] < rhs.m_f[ m_n ] ) return -1;
else if( lhs.m_f[ m_n ] < rhs.m_f[ m_n ] ) return 1;
else return 0;
}
private:
int m_n;
};
The usage is now:
Foo< fields, cmp_field< 0 > > foo( fields( 3, 2, 1 ) );
foo.dosomething( fields( 1, 2, 3 ) );
The above achieves making a STL-like comparison operator to compare
different fields. However, I'd still be interesting in seeing someone
else's angle on this.
Kind Regards,
Jamie
Sorry, the default compare class is:
template< typename T >
class compare : public std::binary_function< T, T, int >
{
public:
compare(){ }
public:
int operator()( const T & lhs, const T & rhs ) const
{
if( lhs < rhs ) return -1;
else if( lhs < rhs ) return 1;
else return 0;
}
};
Not 'bool' like previously specified. This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics
by: BJS |
last post by:
Sorry for the cross-posting, but based on the number of people I have
seen ask for a solution to this problem, I hope by cross-posting this,
that...
|
by: newbiecpp |
last post by:
Why this code cannot be compiled (under VC++ 7.0):
class Outer {
public:
class Inner {
public:
Inner() : in_data(0) {}
void action()
{...
|
by: zhixin_han |
last post by:
Following warnings are found in my application:
..../adm_std_mo_descr.h:240: warning: non-static const member `const
struct std_tee_t...
|
by: mt404 |
last post by:
Hi,
I was wondering if someone might be able to provide some guidance on
how I could make an http request from a C# library.
Basically I have...
|
by: john |
last post by:
I searched http://www.sellsbrothers.com. and could not find anything
about this subject.
How do I make C# User Controls Visible to Visual Basic...
|
by: Tim Marsden |
last post by:
Hi,
I would like to be able to create a page which accepts user input.
When to user press Submit, a long task is performed, and the results...
|
by: Dennis |
last post by:
I have a control that inheirts from "Panel". I want to prevent the user from
having access to the MoueUp event. I tried making a sub in my control...
|
by: Paul Bromley |
last post by:
Forgive my ignorance on this one as I am trying to use a Singleton class. I
need to use this to have one instance of my Class running and I think I...
|
by: RSH |
last post by:
I have a situation where I am working with a user class and I need to
reference the form. Is it best to pass the form object to the constructor
of...
|
by: flopbucket |
last post by:
Hi,
I want to provide a specialization of a class for any type T that is a
std::map.
template<typename T>
class Foo
{
// ...
};
|
by: tammygombez |
last post by:
Hey everyone!
I've been researching gaming laptops lately, and I must say, they can get pretty expensive. However, I've come across some great...
|
by: teenabhardwaj |
last post by:
How would one discover a valid source for learning news, comfort, and help for engineering designs? Covering through piles of books takes a lot of...
|
by: Kemmylinns12 |
last post by:
Blockchain technology has emerged as a transformative force in the business world, offering unprecedented opportunities for innovation and...
|
by: CD Tom |
last post by:
This only shows up in access runtime. When a user select a report from my report menu when they close the report they get a menu I've called Add-ins...
|
by: Naresh1 |
last post by:
What is WebLogic Admin Training?
WebLogic Admin Training is a specialized program designed to equip individuals with the skills and knowledge...
|
by: jalbright99669 |
last post by:
Am having a bit of a time with URL Rewrite. I need to incorporate http to https redirect with a reverse proxy. I have the URL Rewrite rules made...
|
by: antdb |
last post by:
Ⅰ. Advantage of AntDB: hyper-convergence + streaming processing engine
In the overall architecture, a new "hyper-convergence" concept was...
|
by: Matthew3360 |
last post by:
Hi, I have a python app that i want to be able to get variables from a php page on my webserver. My python app is on my computer. How would I make it...
|
by: AndyPSV |
last post by:
HOW CAN I CREATE AN AI with an .executable file that would suck all files in the folder and on my computerHOW CAN I CREATE AN AI with an .executable...
| |