Boost logo

Boost :

From: David Abrahams (dave_at_[hidden])
Date: 2006-03-07 13:22:08

Rene Rivera <grafik.list_at_[hidden]> writes:

> David Abrahams wrote:
>> Rene Rivera <grafik.list_at_[hidden]> writes:
>> Consider the usage you're proposing when you /do/ want a reference to
>> bind to the actual argument:
>> typename binding<Args,tag::k,int>::type const& x = args[k | 0]
>> If the "k" argument wasn't supplied, your int const& will be a
>> dangling reference.
> OK I see it now :-) But it still doesn't change my POV. Here's my
> perspective with regards to the various use cases, when using defaults
> since my initial examples did not use defaults:
> 1. Most of the time I want, and expect, copies.

Okay. I'm not sure why, but that may not matter. What matters is
that it's _your_ desire and expectation. Do we have any reason to
think others will feel the same way?

I have no problem with adding a value_binding<> template that does
what you want, but so far I don't see why we should change binding<>

> And many times this is easy because on just writes out some preset
> type and assign:
> int i = args[something | 1];
> But that use case doesn't, to me, equate to the use case when it's not a
> fixed type:
> typedef remove_reference<remove_const<binding<...>::type>::type T;
> T i = args[something | T(1)];

What do you mean by "equate?" Are you just saying, "it isn't so easy
in that case?"

You know, you can always write this once:

    template <class A, class K, class D = void>
    struct my_binding
      : remove_const<
           typename remove_reference<
               typename binding<A,K,D>::type

> 2. If I'm going to the trouble of getting the reference instead of the
> value. I'm also going to go the extra effort to not get a dangling
> reference as I would have even if I wasn't using boost::parameter:
> int default_i = 0;
> int const & i = args[something | default_i];

That doesn't seem like a good enough reason to make binding<> that
much more unsafe.

> Which also doesn't equate to the case of a variable type:
> typedef remove_reference<remove_const<binding<...>::type>::type T;
> T detault_i(0);
> T const & i = args[something | default_i];
> 3. I can see why having the binding type be a reference would signal
> some forms of dangling refs:
> typedef binding<...>::type T;
> T i = args[something | T()]; // error

Huh? What error? And what is signalled?

> But that seems like a mistake one would make because one is expecting
> the binding type to be the value_type.

I'm lost

> 4. And last, I can't remove_reference< remove_const<X> > on some types.
> In particular last week I was trying to pass in a member function
> pointer. Which the remove_* functions don't work on, or at least they
> don't after boost::parameter adds the "const &".

That should be fixed, then! But are you sure your problem isn't that
you have the remove_ functions inside-out?


That will only remove reference-ness, but not constness, from a
reference-to-const. The following compiles just fine for me, FWIW

  #include <boost/mpl/assert.hpp>
  #include <boost/type_traits/is_same.hpp>
  #include <boost/type_traits/remove_const.hpp>
  #include <boost/type_traits/remove_reference.hpp>

  struct X { int g(); };

  template <class T> int f(T const& x)
      using namespace boost;
      typedef T const& tcr;

              typename remove_const<
                  typename remove_reference< tcr >::type
          , T>));

      return 0;

  int x = f(&X::g);

But if I invert the const and reference, of course it fails.

> So I ended up having to use a boost::function instead.


> Basically it seems like I end up having to jump through hoops in
> many use cases just to gain that compiler error on 1 use case and
> the default value_type in 1 other use case. Maybe I'm just weird and
> I would see things differently if I used things like the macros and
> forwarding functions.

Sorry, I'm totally lost.

Dave Abrahams
Boost Consulting

Boost list run by bdawes at, gregod at, cpdaniel at, john at