Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > returned type of boost::bind && Address of a tmp object

Reply
Thread Tools

returned type of boost::bind && Address of a tmp object

 
 
Giovanni Gherdovich
Guest
Posts: n/a
 
      08-28-2008
Hello,

in the following code I have a pointer (to function), say p,
of type
double (*)(double, double, void*)
and I try to fix the second argument of the function *p
to a given value (using boost::bind), but the compiler
complains, because of a type mismatch in an assignment
which I think should be legal:

/*
* bash-3.00$ g++ function.cpp
* function.cpp: In function `int main()':
* function.cpp:36: warning: taking address of temporary
* function.cpp:36: error: cannot convert
* `boost::_bi::bind_t<double,
* double (*)(double, double, void*),
* boost::_bi::list3<boost::arg<1>,
*
boost::_bi::value<double>,
* boost::arg<2> > >*'
* to `double (*)(double, void*)' in assignment
*/

Can you see why? The code is below.

There is also a warning which I don't like at all,
and remebers me that boost::bind( ... ) is a temporary
object and its address makes sense only in the current
scope (if I'm not wrong).
Since I have to pass this address as argument to another
function (later, in my real code), this can couse problems.

How can I build a "real" (I mean non-temporary) object
out of boost::bind( ... ), so that its address can
be passed forth and back across my code?

Regards,
Giovanni


// ---------------------------------------------- the file
function.cpp
#include <boost/bind.hpp>

struct oneVar_function // one variable function
{
double (* function) (double x, void* params);
void* params;
};

struct twoVar_function // two variables function
{
double (* function) (double x, double y, void* params);
void* params;
};

double
my_function (double x, double y, void* params)
{
// I cast `params` to double*.
// The user will be kind enough to always
// give a double* as 3rd argument when
// calling my_function.
double* alpha = static_cast<double*>(params);
return x + y + *alpha; // or whatever
}

int main()
{
twoVar_function f;
oneVar_function g;

f.function = &my_function;
double alpha = 3;
f.params = &alpha;

double a_given_number = 2;
g.function = &(boost::bind(*(f.function),
_1,
a_given_number,
_2));
g.params = &alpha;
}
// -------------------------------------- end of the file function.cpp
 
Reply With Quote
 
 
 
 
Eric.Malenfant@gmail.com
Guest
Posts: n/a
 
      08-28-2008
On Aug 28, 2:18*pm, Giovanni Gherdovich
<gherdov...@students.math.unifi.it> wrote:
> Hello,
>
> in the following code I have a pointer (to function), say p,
> of type
> double (*)(double, double, void*)
> and I try to fix the second argument of the function *p
> to a given value (using boost::bind), but the compiler
> complains, because of a type mismatch in an assignment
> which I think should be legal:
>
> /*
> ** *bash-3.00$ g++ function.cpp
> ** *function.cpp: In function `int main()':
> ** *function.cpp:36: warning: taking address of temporary
> ** *function.cpp:36: error: cannot convert
> ** * * * * `boost::_bi::bind_t<double,
> ** * * * * * * * * * * * * * * double (*)(double, double, void*),
> ** * * * * * * * * * * * * * * boost::_bi::list3<boost::arg<1>,
> **
> boost::_bi::value<double>,
> ** * * * * * * * * * * * * * * * * * * * * * * * boost::arg<2> > >*'
> ** * * * * * to `double (*)(double, void*)' in assignment
> **/
>


The compiler message says that the result of boost::bind is not
convertible to a function pointer.
boost::bind is a function template which returns an object (the type
of this object is a function of the parameters passed to the
boost::bind invocation), not an "ordinary" function.

The warning about taking the address of a temporary is because your
code takes the address of that object returned by boost::bind.

> How can I build a "real" (I mean non-temporary) object
> out of boost::bind( ... ), so that its address can
> be passed forth and back across my code?


Have a look at boost::function: http://www.boost.org/doc/libs/1_36_0.../function.html

HTH,

Éric Malenfant
 
Reply With Quote
 
 
 
 
gpderetta
Guest
Posts: n/a
 
      08-28-2008
On Aug 28, 8:18*pm, Giovanni Gherdovich
<gherdov...@students.math.unifi.it> wrote:
> Hello,
>
> in the following code I have a pointer (to function), say p,
> of type
> double (*)(double, double, void*)
> and I try to fix the second argument of the function *p
> to a given value (using boost::bind), but the compiler
> complains, because of a type mismatch in an assignment
> which I think should be legal:
>


<snip>
>
> Can you see why? The code is below.
>
> There is also a warning which I don't like at all,
> and remebers me that boost::bind( ... ) is a temporary
> object and its address makes sense only in the current
> scope (if I'm not wrong).
> Since I have to pass this address as argument to another
> function (later, in my real code), this can couse problems.
>
> How can I build a "real" (I mean non-temporary) object
> out of boost::bind( ... ), so that its address can
> be passed forth and back across my code?
>


<snip>
> struct oneVar_function *// one variable function
> {
> * double (* function) (double x, void* params);
> * void* params;
>
> };


<snip>

>
> * double a_given_number = 2;
> * g.function = &(boost::bind(*(f.function),
> * * * * * * * * * * * * * * *_1,
> * * * * * * * * * * * * * * *a_given_number,
> * * * * * * * * * * * * * * *_2));


'Bind' does not return a function pointer but an unspecified function
object (sort of a closure).

Thus there are two problems: first the assignment is illegal: you are
trying to convert a pointer to such a function object to a pointer to
a function. Second, as the compiler warns you, grabbing the address of
the temporary object returned by bind is a dangerous action, because
the temporary will be destroyed at the end of the expression.

As the exact result type of 'bind' is unspecified (well, you can see
it in the error message, but you shouldn't rely on it), you will have
to use boost::function as the type of the 'function' member of
oneVar_function:

#include <boost/function.hpp>
struct oneVar_function // one variable function
{
boost::function<double (double x, void* params)> function;
void* params;
};

[note: unteste code]
Note that boost::function can store function pointers as well as
function objects.

--
gpd

 
Reply With Quote
 
Giovanni Gherdovich
Guest
Posts: n/a
 
      08-28-2008
Hello,

thank you for your answers.

Eric:
> Have a look at boost::function


gpd:
> As the exact result type of 'bind' is unspecified (well, you can see
> it in the error message, but you shouldn't rely on it), you will have
> to use boost::function as the type of the 'function' member of
> oneVar_function: [...]


I implemented my (wanna-be) callbacks as boost::function instead of
function pointers, and the two problems I mentioned in my previous
post are gone.

Furthermore I feel that switching the whole design of my real code
to boost::function will be straightforward. Cool!

Here is the modified version of my toy example, which compiles
and works fine:

// ---------------- this is the file function2.cpp
#include <boost/bind.hpp>
#include <boost/function.hpp>
#include <iostream>

struct oneVar_function // one variable function
{
boost::function<double (double x, void* params)> function;
void* params;
};

struct twoVar_function // two variables function
{
boost::function<double (double x, double y, void* params)> function;
void* params;
};

double
my_function (double x, double y, void* params)
{
// I cast `params` to double*.
// The user will be kind enough to always
// give a double* as 3rd argument when
// calling my_function.
double* alpha = static_cast<double*>(params);
return x + y + *alpha; // or whatever
}

int main()
{
double alpha = 3;
twoVar_function f;
oneVar_function g;

f.function = &my_function;
f.params = &alpha;

double a_given_number = 2;
g.function = boost::bind(f.function,
_1,
a_given_number,
_2);
g.params = &alpha;

std::cout << (f.function)(1, 2, f.params) << std::endl;
// expected: 6
std::cout << (g.function)(1, g.params) << std::endl;
// expected: 6

/*
* bash-3.00$ g++ function2.cpp
* bash-3.00$ ./a.out
* 6
* 6
* bash-3.00$
*/
}
// ---------------- end of file function2.cpp
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Type object returned by the re.compile function candide Python 2 12-27-2011 10:31 PM
"gridview Object does not match target type" error during binding collection of different type object gui.besse@gmail.com ASP .Net 2 08-06-2006 03:12 PM
Created object on stack and then returned this object to caller. Item deleted but still there?? opistobranchia C++ 1 08-14-2005 07:51 PM
Changing dir for tmp files Ed Mullen Firefox 0 03-06-2004 03:52 AM
Does the whole .tmp, wwroot$, file share debacle, come down to..... John Sitka ASP .Net 0 07-17-2003 02:13 PM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57