Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   C++ (http://www.velocityreviews.com/forums/f39-c.html)
-   -   reference to reference and constness problems with bind1st (http://www.velocityreviews.com/forums/t284192-reference-to-reference-and-constness-problems-with-bind1st.html)

Marc 07-05-2004 06:21 PM

reference to reference and constness problems with bind1st
 
T x;
T foo(T, T);
bind1st(ptr_fun(foo), x)

creates a function object that takes an argument of type T const&. This
does not work if T is already a reference type like int const&. So my
first problem is with the &. My second problem is with the const. Why
should bind1st change the constness of the second argument of the
function*?

I am currently using boost::bind instead, but I would rather not depend
on boost for all my programs...

Denis Remezov 07-06-2004 01:46 AM

Re: reference to reference and constness problems with bind1st
 
Marc wrote:
>
> T x;
> T foo(T, T);
> bind1st(ptr_fun(foo), x)
>
> creates a function object that takes an argument of type T const&. This
> does not work if T is already a reference type like int const&. So my
> first problem is with the &. My second problem is with the const. Why
> should bind1st change the constness of the second argument of the
> function ?
>


If instead of bind1st(Op const& op, T const& y) we had
bind1st(Op const& op, T& y), it would cause a problem deducing a
const reference template argument when used with, e.g. a temporary
or a numeric literal:
bind1st(ptr_fun(foo), 13);

The deduced type of template parameter T would be int, not const int,
T& would not bind to the argument, and the above would fail to compile.


> I am currently using boost::bind instead, but I would rather not depend
> on boost for all my programs...


You could change the parameters of foo from references to pointers.

When I was experimenting with this problem (and couldn't use boost)
I came up with a rather uncouth alternative of duplicating the standard
bind1st for the case when the template parameters are references (I've
never used it for real though):

template <class Op>
class refbinder1st : public unary_function<typename Op::second_argument_type,
typename Op::result_type> {
protected:
Op op_;
typename Op::first_argument_type val_;
public:
refbinder1st(const Op& op,
const typename Op::first_argument_type val) : op_(op),
val_(val) {}
typename Op::result_type operator ()(
const typename Op::second_argument_type arg) const {
return op_(val_, arg);
}
};

// Both arguments of Op should be references or very small objects
template <class Op, typename T>
refbinder1st<Op> refbind1st(const Op& op, T v_1st) {
return refbinder1st<Op>(op, typename Op::first_argument_type(v_1st));
}


Denis

tom_usenet 07-06-2004 09:24 AM

Re: reference to reference and constness problems with bind1st
 
On Mon, 5 Jul 2004 18:21:50 +0000 (UTC), Marc <MarcDotGlisse@Loria.Fr>
wrote:

> T x;
> T foo(T, T);
> bind1st(ptr_fun(foo), x)
>
>creates a function object that takes an argument of type T const&. This
>does not work if T is already a reference type like int const&. So my
>first problem is with the &. My second problem is with the const. Why
>should bind1st change the constness of the second argument of the
>function*?


Just the way it is written. Perfect argument passing is an unsolved
problem of C++, although the next version of the standard is going to
address it I think. In the absense of perfect argument passing, old
code used const references. Some new code uses more sophisticated
schemes, such as the call_traits in boost, or even rvalue/lvalue/const
resolving stuff (e.g. Mojo).

>
>I am currently using boost::bind instead, but I would rather not depend
>on boost for all my programs...


Boost contains too much essential stuff not to depend on it. I'd just
end up rewriting half of it if I couldn't use it. However, you can
just lift out the <boost/functional.hpp> header for a replacement
<functional> header that works much better.

Tom
--
C++ FAQ: http://www.parashift.com/c++-faq-lite/
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html

Marc 07-06-2004 12:49 PM

Re: reference to reference and constness problems with bind1st
 
Denis Remezov wrote:

> If instead of bind1st(Op const& op, T const& y) we had
> bind1st(Op const& op, T& y), it would cause a problem deducing a
> const reference template argument when used with, e.g. a temporary
> or a numeric literal:
> bind1st(ptr_fun(foo), 13);
>
> The deduced type of template parameter T would be int, not const int,
> T& would not bind to the argument, and the above would fail to compile.


I thought that it could be overloaded with a const and a non-const
versions. But I don't have time to check.

> When I was experimenting with this problem (and couldn't use boost)
> I came up with a rather uncouth alternative of duplicating the standard
> bind1st for the case when the template parameters are references (I've
> never used it for real though):


That is interesting, and it seems to work fine. Thank you for your
answer.


Marc 07-06-2004 01:00 PM

Re: reference to reference and constness problems with bind1st
 
tom_usenet wrote:

> Just the way it is written. Perfect argument passing is an unsolved
> problem of C++, although the next version of the standard is going to
> address it I think.


Do you have a reference on this "perfect argument passing" issue*?

> Boost contains too much essential stuff not to depend on it. I'd just
> end up rewriting half of it if I couldn't use it. However, you can
> just lift out the <boost/functional.hpp> header for a replacement
> <functional> header that works much better.


Cool, I had not seen this in boost. I hope the next standard benefits
from it.

Thank you for your answer.

tom_usenet 07-06-2004 01:36 PM

Re: reference to reference and constness problems with bind1st
 
On Tue, 6 Jul 2004 13:00:43 +0000 (UTC), Marc <MarcDotGlisse@Loria.Fr>
wrote:

>tom_usenet wrote:
>
>> Just the way it is written. Perfect argument passing is an unsolved
>> problem of C++, although the next version of the standard is going to
>> address it I think.

>
>Do you have a reference on this "perfect argument passing" issue*?


http://www.open-std.org/jtc1/sc22/wg...2002/n1385.htm

>> Boost contains too much essential stuff not to depend on it. I'd just
>> end up rewriting half of it if I couldn't use it. However, you can
>> just lift out the <boost/functional.hpp> header for a replacement
>> <functional> header that works much better.

>
>Cool, I had not seen this in boost. I hope the next standard benefits
>from it.


Unlikely I think, but boost::bind is part of the standard library
technical report (so it will be std::tr1::bind, and should come with
your compiler):
http://www.open-std.org/jtc1/sc22/wg...al_report.html
It's due in the next year.

Tom
--
C++ FAQ: http://www.parashift.com/c++-faq-lite/
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html

Denis Remezov 07-06-2004 02:01 PM

Re: reference to reference and constness problems with bind1st
 
Marc wrote:
>
> Denis Remezov wrote:
>
> > If instead of bind1st(Op const& op, T const& y) we had
> > bind1st(Op const& op, T& y), it would cause a problem deducing a
> > const reference template argument when used with, e.g. a temporary
> > or a numeric literal:
> > bind1st(ptr_fun(foo), 13);
> >
> > The deduced type of template parameter T would be int, not const int,
> > T& would not bind to the argument, and the above would fail to compile.

>
> I thought that it could be overloaded with a const and a non-const
> versions. But I don't have time to check.
>


Yes, but the problem is the automatic template parameter deduction:

template <typename T>
void f(T& v) {
}

int main() {
const int a=13;
f(a); //all right

f<int const>(13); //all right as well

f(13); //error
}

Denis


All times are GMT. The time now is 05:36 PM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.