|
Boost Users : |
Subject: Re: [Boost-users] [boost-users][bind, lambda, ...] binding unused actual parameter
From: Gottlob Frege (gottlobfrege_at_[hidden])
Date: 2009-04-16 13:12:51
It might be nice if the new code included a comment explaining the reasoning.
On Thursday, April 16, 2009, Roman Perepelitsa
<roman.perepelitsa_at_[hidden]> wrote:
> 2009/4/16 Igor R <boost.lists_at_[hidden]>
>
>
> Well, it turns out that defining get_pointer() for ATL::CComPtr won't
> help, because CComPtrBase defines its own operator&(), doing this in a
> pretty weird way (quote from atlcomcli.h):
>
> //The assert on operator& usually indicates a bug. If this is really
> //what is needed, however, take the address of the p member explicitly.
> T** operator&() throw()
> {
> ATLASSERT(p==NULL);
> return &p;
> }
>
> So the "double bind" is the only short way to do this.
>
> Ah, I see why it happens. To distinguish between regular objects and smart pointers, mem_fn does the following trick:
> void call(const T*) { /* it's a regular object */ }
> void call(const void*) { /* it might be a smart pointer */ } void test(U& t) { call(&t); }
>
> If U is CComPtr<T>, taking its address triggers an assert. It can be easily fixed though.
> void test(U& t) { call(false ? &t : 0); }
>
> Now type of the expression &t is used for choosing the right overload of call, but operator& is not applied in runtime.
>
> Here's the patch against trunk:
> --- mem_fn_template.hpp (revision 52422)+++ mem_fn_template.hpp (working copy)
> @@ -51,14 +51,14 @@ template<class U> R operator()(U & u) const
> {- BOOST_MEM_FN_RETURN call(u, &u);
> + BOOST_MEM_FN_RETURN call(u, false ? &u : 0); }
> #ifdef BOOST_MEM_FN_ENABLE_CONST_OVERLOADS
> template<class U> R operator()(U const & u) const {
> - BOOST_MEM_FN_RETURN call(u, &u);+ BOOST_MEM_FN_RETURN call(u, false ? &u : 0);
> } #endif
>
> And here is the test:
> #include <cstdlib>#include <boost/bind.hpp>
> struct foo{
> void bar() {}} f;
> struct ptr{
> void* operator&() { std::abort(); }};
> foo* get_pointer(const ptr& p) { return &f; }
> int main() { boost::bind(&foo::bar, ptr())();
> }
>
> Roman Perepelitsa.
>
Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net