std::binary_function

Y

yurec

Hi all.

Compiling following in vs2005 i get compile error error C2440:
'<function-style-cast>' : cannot convert from 'overloaded-function' to
'std::binary_function<_Arg1,_Arg2,_Result>'.Any comments, please.

#include <vector>
#include <string>
#include <functional>

class A{};
class B{};

namespace SomeNamespace
{
void Check(A a, std::string str);
void Check(B b, std::string str);

template<class Container>
void Check(const Container & objects)
{
typedef typename Container::value_type ObjectType;
using namespace std;
for_each(objects.begin(),objects.end(),

bind2nd(binary_function<ObjectType,string,void>(Check),string("")));
}
}

int main()
{
std::vector<A> vector_of_a;
SomeNamespace::Check(vector_of_a);
return 0;
}
 
O

Obnoxious User

Hi all.

Compiling following in vs2005 i get compile error error C2440:
'<function-style-cast>' : cannot convert from 'overloaded-function' to
'std::binary_function<_Arg1,_Arg2,_Result>'.Any comments, please.

#include <vector>
#include <string>
#include <functional>

class A{};
class B{};

namespace SomeNamespace
{
void Check(A a, std::string str);
void Check(B b, std::string str);

template<class Container>
void Check(const Container & objects)
{
typedef typename Container::value_type ObjectType; using namespace
std;
for_each(objects.begin(),objects.end(),

bind2nd(binary_function<ObjectType,string,void>(Check),string("")));

Do you even know the purpose of std::binary_function?
 
B

brian tyler

std::binary_function is a struct containing 3 typedefs:
first_argument_type, second_argument_type and result_type. You inherit
from it to give binary function objects a common interface, apart from
that it is totally useless :)
 
Y

yurec

std::binary_function is a struct containing 3 typedefs:
first_argument_type, second_argument_type and result_type. You inherit
from it to give binary function objects a common interface, apart from
that it is totally useless :)

Hi, thx.
So what is the way to use free function with more then single
parameter as _Pred ?
 
B

brian tyler

std::for_each allows you to iterate over range of type T and apply a
unary (one argument) function object or function pointer to each
element in the range. The argument of this function is of type R where
T is convertible to R ( ie R is probably T, const T, T& or const T& )

for example:

#include <functional>
#include <algorithm>
#include <vector>
#include <iostream>

struct average : public std::unary_function<double,void>
{
double sum_;
long count_;

average() : sum_(0), count_(0) {}
void operator()(double value){ sum_ += value; ++count_; }
operator double () { return double( sum_ / count_ ); }
};

int main() {
using namespace std;
std::vector<double> v;

for(int i = 1; i != 11; ++i ) { v.push_back(i); }
cout << for_each( v.begin(), v.end(), average() ) << endl;

return 0;
}

outputs 5.5

It is not possible to pass in a second argument to for_each because it
requires a unary function, although you can bind an argument to a
binary function (this all gets rather complicated). To get around this
you may want to write a function object wrapper.

To be honest, if you don't know what for_each does or what a function
object is then you should probably get to grips with them before
trying fancy stuff.

Good luck,
Brian
 
Y

yurec

Hi Brian,
It is not possible to pass in a second argument to for_each because it
requires a unary function, although you can bind an argument to a
binary function (this all gets rather complicated). To get around this
you may want to write a function object wrapper.
although you can bind an argument to a
binary function (this all gets rather complicated)

That is exactly i wanted to implement.
And the question i asked was to show me how it should look like.
To be honest, if you don't know what for_each does or what a function
object is then you should probably get to grips with them before
trying fancy stuff.

I used to work with boost::bind instead of stl's functors.

Regards,
Yurij
 
J

Jerry Coffin

Hi all.

Compiling following in vs2005 i get compile error error C2440:
'<function-style-cast>' : cannot convert from 'overloaded-function' to
'std::binary_function<_Arg1,_Arg2,_Result>'.Any comments, please.

Normally you inherit from binary_function to allow a function to be used
by something in the standard library. You normally use unary_function
the same way. For example, to compute the variance of a set of numbers,
you take each number, subtract it from the average, square the
difference, and then average all those results. Using loops, it would
look something like this:

double average=0.0;

for (int i=0; i<v.size(); i++)
average +=v;

average /= v.size();

double squares = 0.0;
for (int i=0; i<v.size(); i++) {
double temp = v - average;
squares += temp * temp;
}

double variance = squares / v.size();

using algorithms instead, we could do something like this:

struct diff2 : public std::binary_function<double, double, double> {
double average_;
public:
diff2(double average) : average_(average) {}
double operator()(double total, double value) {
double temp = value - average_;
return total + temp * temp;
}
};

double mean = std::accumulate(v.begin(), v.end(), 0.0) / v.size();

double chi2 = std::accumulate(v.begin(), v.end(), 0.0, diff2(mean))
/ (v.size()-1.0);
 
T

Triple-DES

Hi all.

Compiling following  in vs2005 i get compile error error C2440:
'<function-style-cast>' : cannot convert from 'overloaded-function' to
'std::binary_function<_Arg1,_Arg2,_Result>'.Any comments, please.

#include <vector>
#include <string>
#include <functional>

class A{};
class B{};

namespace SomeNamespace
  {
  void Check(A a, std::string str);
  void Check(B b, std::string str);

  template<class Container>
  void Check(const Container & objects)
    {
    typedef typename Container::value_type ObjectType;
    using namespace std;
    for_each(objects.begin(),objects.end(),

bind2nd(binary_function<ObjectType,string,void>(Check),string("")));
    }
  }

int main()
  {
  std::vector<A> vector_of_a;
  SomeNamespace::Check(vector_of_a);
  return 0;
  }

what you probably want is:

bind2nd( ptr_fun(Check), string(""))

However, since the Check function is overloaded in your example, you
need to use a cast to get the correct one.

bind2nd( ptr_fun( static_cast<void (*)(ObjectType, string)>(Check)),
string("") )

Hope this helps
DP
 
Y

yurec

what you probably want is:

bind2nd( ptr_fun(Check), string(""))

However, since the Check function is overloaded in your example, you
need to use a cast to get the correct one.

bind2nd( ptr_fun( static_cast<void (*)(ObjectType, string)>(Check)),
string("") )

Hope this helps
DP- Hide quoted text -

- Show quoted text -

Yes, thx.
 
P

Pete Becker

Normally you inherit from binary_function to allow a function to be used
by something in the standard library. You normally use unary_function
the same way.

True, but just to make it absolutely clear: binary_function and
unary_function aren't required; they're for convenience (and some think
they're pretty inconvenient). The requirement in some contexts is that
a callable type that can be called with one argument have two nested
typedefs, one that defines an alias named 'result_type' and one that
defines an alias named 'argument_type'. Similarly, for two arguments
there are three typedefs: result_type, first_argument_type, and
second_argument_type. One way to get those typedefs is to derive from
unary_function or binary_function, as appropriate. Another way is
simply to write them in your class. There's no reason for production
code to contain functions that take unary_function or binary_function.
They don't do anything except provide those definitions.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,012
Latest member
RoxanneDzm

Latest Threads

Top