reference to reference and constness problems with bind1st

Discussion in 'C++' started by Marc, Jul 5, 2004.

  1. Marc

    Marc Guest

    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...
    Marc, Jul 5, 2004
    #1
    1. Advertising

  2. 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
    Denis Remezov, Jul 6, 2004
    #2
    1. Advertising

  3. Marc

    tom_usenet Guest

    On Mon, 5 Jul 2004 18:21:50 +0000 (UTC), 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 ?


    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
    tom_usenet, Jul 6, 2004
    #3
  4. Marc

    Marc Guest

    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, Jul 6, 2004
    #4
  5. Marc

    Marc Guest

    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.
    Marc, Jul 6, 2004
    #5
  6. Marc

    tom_usenet Guest

    On Tue, 6 Jul 2004 13:00:43 +0000 (UTC), Marc <>
    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/wg21/docs/papers/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/wg21/docs/library_technical_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
    tom_usenet, Jul 6, 2004
    #6
  7. 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
    Denis Remezov, Jul 6, 2004
    #7
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. wenmang
    Replies:
    1
    Views:
    494
    Victor Bazarov
    Aug 8, 2003
  2. Denis Remezov

    binary_function and bind1st

    Denis Remezov, May 19, 2004, in forum: C++
    Replies:
    6
    Views:
    747
    P.J. Plauger
    May 21, 2004
  3. Alberto
    Replies:
    1
    Views:
    1,303
    Clark S. Cox III
    Feb 7, 2005
  4. Replies:
    14
    Views:
    826
    Ian Collins
    Apr 4, 2006
  5. Marcel Müller

    reference counting and constness

    Marcel Müller, Dec 23, 2012, in forum: C++
    Replies:
    3
    Views:
    231
    James Kanze
    Dec 28, 2012
Loading...

Share This Page