Using find_if STL function [modified]
-
Hi, I am trying to use find_if STL method for learning purpose. I have an array of structure as struct NewPriceLookup { NewPriceLookup() : m_oldprice(0.0), m_newprice(0.0) {} NewPriceLookup(const double& oldp, const double& newp): m_oldprice(oldp), m_newprice(newp) {} double m_oldprice; double m_newprice; }; NewPriceLookup npLookup [5] = {NewPriceLookup(10.0, 12.0), NewPriceLookup(12.0, 14.5), NewPriceLookup(15.0, 17.0), NewPriceLookup(22.0, 26.0), NewPriceLookup(30.0, 35.0) }; vector OldNewPriceTable(&npLookup[0], &npLookup(5)); template struct NewPriceGrabber : public binary_function { result_type operator()(first_argument_type arg1, second_argument_type arg2) { return (arg1.m_oldprice == arg2); } }; and somewhere in the method GetNewPrices() I am trying to do the following ..... ..... double oldprice = 15.0; double newprice = find_if( OldNewPriceTable.begin(), OldNewPriceTable.end(), bind2nd(NewPriceGrabber(), oldprice)); When I compile this code, I am getting all sorts of errors like pointer_to_binary_function expects 2 argument 1 provided, cannot deduce template argument etc... Can someone please help me in getting this piece of code right? Thanks in advance. :confused::confused:
modified on Sunday, February 24, 2008 12:42 PM
-
Hi, I am trying to use find_if STL method for learning purpose. I have an array of structure as struct NewPriceLookup { NewPriceLookup() : m_oldprice(0.0), m_newprice(0.0) {} NewPriceLookup(const double& oldp, const double& newp): m_oldprice(oldp), m_newprice(newp) {} double m_oldprice; double m_newprice; }; NewPriceLookup npLookup [5] = {NewPriceLookup(10.0, 12.0), NewPriceLookup(12.0, 14.5), NewPriceLookup(15.0, 17.0), NewPriceLookup(22.0, 26.0), NewPriceLookup(30.0, 35.0) }; vector OldNewPriceTable(&npLookup[0], &npLookup(5)); template struct NewPriceGrabber : public binary_function { result_type operator()(first_argument_type arg1, second_argument_type arg2) { return (arg1.m_oldprice == arg2); } }; and somewhere in the method GetNewPrices() I am trying to do the following ..... ..... double oldprice = 15.0; double newprice = find_if( OldNewPriceTable.begin(), OldNewPriceTable.end(), bind2nd(NewPriceGrabber(), oldprice)); When I compile this code, I am getting all sorts of errors like pointer_to_binary_function expects 2 argument 1 provided, cannot deduce template argument etc... Can someone please help me in getting this piece of code right? Thanks in advance. :confused::confused:
modified on Sunday, February 24, 2008 12:42 PM
First thing - what compiler are you using? If it's VC++ 6, then....upgrade if at all possible! I've just compiled your code with VC++2005 and it seems fine, aside from a) needing
const
qualification onNewPriceGrabber
'soperator()
, b) this linedouble newprice = find_if( OldNewPriceTable.begin(), OldNewPriceTable.end(),
bind2nd(NewPriceGrabber<NewPriceLookup, double, bool>(), oldprice));which returns a vector iterator, not a double:
std::vector<NewPriceLookup>::const_iterator it = std::find_if( OldNewPriceTable.begin(), OldNewPriceTable.end(),
bind2nd(NewPriceGrabber<NewPriceLookup, double, bool>(), oldprice));and c) I presume the '
&npLookup**(**5**)**
' is a typo, 'should be '&npLookup**[**5**]**
'. My other advice would be to use Boost.Bind[^] or Boost.Lambda[^] for function binders - I find them a lot less confusing. Your example would translate to:bool NewPriceGrabber(NewPriceLookup const& arg1, double price)
{
return (arg1.m_oldprice == price);
}void x()
{
double oldprice = 15.0;
std::vector<NewPriceLookup>::const_iterator it = std::find_if( OldNewPriceTable.begin(), OldNewPriceTable.end(),
boost::bind(NewPriceGrabber, _1, oldprice));
}Two advantages - 1) no functio
-
Hi, I am trying to use find_if STL method for learning purpose. I have an array of structure as struct NewPriceLookup { NewPriceLookup() : m_oldprice(0.0), m_newprice(0.0) {} NewPriceLookup(const double& oldp, const double& newp): m_oldprice(oldp), m_newprice(newp) {} double m_oldprice; double m_newprice; }; NewPriceLookup npLookup [5] = {NewPriceLookup(10.0, 12.0), NewPriceLookup(12.0, 14.5), NewPriceLookup(15.0, 17.0), NewPriceLookup(22.0, 26.0), NewPriceLookup(30.0, 35.0) }; vector OldNewPriceTable(&npLookup[0], &npLookup(5)); template struct NewPriceGrabber : public binary_function { result_type operator()(first_argument_type arg1, second_argument_type arg2) { return (arg1.m_oldprice == arg2); } }; and somewhere in the method GetNewPrices() I am trying to do the following ..... ..... double oldprice = 15.0; double newprice = find_if( OldNewPriceTable.begin(), OldNewPriceTable.end(), bind2nd(NewPriceGrabber(), oldprice)); When I compile this code, I am getting all sorts of errors like pointer_to_binary_function expects 2 argument 1 provided, cannot deduce template argument etc... Can someone please help me in getting this piece of code right? Thanks in advance. :confused::confused:
modified on Sunday, February 24, 2008 12:42 PM
A couple of other suggestions re: STL
- For a simple lookup table, a
map
would be the preferred container, rather than use a vector of structures:
#include <map>
typedef std::map<double, double> NewPriceLookup;
void x()
{
double oldprice = 15.0;
NewPriceLookup npLookup;
npLookup.insert(std::make_pair(10.0, 12.0));
npLookup.insert(std::make_pair(12.0, 14.5));
npLookup.insert(std::make_pair(15.0, 17.0));
npLookup.insert(std::make_pair(22.0, 26.0));
npLookup.insert(std::make_pair(30.0, 35.0));
NewPriceLookup::const_iterator it = npLookup.find(oldprice);
}If you want to initialise a
map
, you can use Boost.Assign[^].operator()
in function objects should generally be defined to take arguments (especially structs/classes) by const reference rather than by value - it minimizes copying. Also,operator()
should in general beconst
-qualified - it's all part ofconst
-correctness.
- For a simple lookup table, a
-
A couple of other suggestions re: STL
- For a simple lookup table, a
map
would be the preferred container, rather than use a vector of structures:
#include <map>
typedef std::map<double, double> NewPriceLookup;
void x()
{
double oldprice = 15.0;
NewPriceLookup npLookup;
npLookup.insert(std::make_pair(10.0, 12.0));
npLookup.insert(std::make_pair(12.0, 14.5));
npLookup.insert(std::make_pair(15.0, 17.0));
npLookup.insert(std::make_pair(22.0, 26.0));
npLookup.insert(std::make_pair(30.0, 35.0));
NewPriceLookup::const_iterator it = npLookup.find(oldprice);
}If you want to initialise a
map
, you can use Boost.Assign[^].operator()
in function objects should generally be defined to take arguments (especially structs/classes) by const reference rather than by value - it minimizes copying. Also,operator()
should in general beconst
-qualified - it's all part ofconst
-correctness.
Hi Stuart, Thanks for your suggestions. Using STL map was so simple, I didn't realized it earlier but anyways I did wanted to learn the usage of find_if method. I will also look into Boost libraries once I have a bit more confidence in STL itself. Regards. :) :)
- For a simple lookup table, a
-
Hi Stuart, Thanks for your suggestions. Using STL map was so simple, I didn't realized it earlier but anyways I did wanted to learn the usage of find_if method. I will also look into Boost libraries once I have a bit more confidence in STL itself. Regards. :) :)
psychedelic_fur wrote:
but anyways I did wanted to learn the usage of find_if method.
Good plan! I did wonder whether "learning to use STL" was the reason you were using vector & find_if rather than map.
psychedelic_fur wrote:
I will also look into Boost libraries once I have a bit more confidence in STL itself.
I'll just reiterate that (IMO) Boost binders are a lot easier to get to grips with than STL binders - I have always had trouble working out exactly what bind2nd and bind1st will produce.
-
psychedelic_fur wrote:
but anyways I did wanted to learn the usage of find_if method.
Good plan! I did wonder whether "learning to use STL" was the reason you were using vector & find_if rather than map.
psychedelic_fur wrote:
I will also look into Boost libraries once I have a bit more confidence in STL itself.
I'll just reiterate that (IMO) Boost binders are a lot easier to get to grips with than STL binders - I have always had trouble working out exactly what bind2nd and bind1st will produce.
Yes I did used vector for that purpose, may be my example was not good. I would really like to understand STL first before using Boost. Even though boost make the life simple it does hide you from lots of internal details and I do not want to miss on those details. Thanks & Regards. :) :)
-
Hi, I am trying to use find_if STL method for learning purpose. I have an array of structure as struct NewPriceLookup { NewPriceLookup() : m_oldprice(0.0), m_newprice(0.0) {} NewPriceLookup(const double& oldp, const double& newp): m_oldprice(oldp), m_newprice(newp) {} double m_oldprice; double m_newprice; }; NewPriceLookup npLookup [5] = {NewPriceLookup(10.0, 12.0), NewPriceLookup(12.0, 14.5), NewPriceLookup(15.0, 17.0), NewPriceLookup(22.0, 26.0), NewPriceLookup(30.0, 35.0) }; vector OldNewPriceTable(&npLookup[0], &npLookup(5)); template struct NewPriceGrabber : public binary_function { result_type operator()(first_argument_type arg1, second_argument_type arg2) { return (arg1.m_oldprice == arg2); } }; and somewhere in the method GetNewPrices() I am trying to do the following ..... ..... double oldprice = 15.0; double newprice = find_if( OldNewPriceTable.begin(), OldNewPriceTable.end(), bind2nd(NewPriceGrabber(), oldprice)); When I compile this code, I am getting all sorts of errors like pointer_to_binary_function expects 2 argument 1 provided, cannot deduce template argument etc... Can someone please help me in getting this piece of code right? Thanks in advance. :confused::confused:
modified on Sunday, February 24, 2008 12:42 PM
Just a tip for coming exercises: Never compare floating point types for equality. Only use integral types for equality comparisons. Floating point types should be compared by checking if their difference is smaller than some defined tolerance.
-- Time you enjoy wasting is not wasted time - Bertrand Russel