Opened 18 years ago

Closed 18 years ago

Last modified 18 years ago

#301 closed Bugs (None)

boost::function doesn't accept classes declared in functions

Reported by: nobody Owned by: Douglas Gregor
Milestone: Component: functional
Version: None Severity:
Keywords: Cc:

Description

Submitter:
John Engström
<john.engstrom\"\s\p\a\m\"@\"\s\p\a\m\"solcorp.com>

Using MSVC 7.1, I use a functor defined in-scope, as in
the following example.

///////////////////// code snippet

void bar()
{
    ...

    struct my_functor
    {
        void operator () (int arg1, int arg2) {

            ...
            foo();
            ...
        }

        ...
    };

    my_functor my_functor_instance;

    boost::function2<void, int, int> my_function1 =
boost::ref(my_functor_instance);
    boost::function2<void, int, int> my_function2 =
my_functor_instance;
}

/////////////////// explanation

This fails to compile, see below for error messages,
however if I move the declaration of the functor out of
the function bar(), it compiles fine. Perhaps it only
happens with MSVC.

/////////////////// error messages

main.cpp(116): error C2893: Failed to specialize
function template 'const boost::reference_wrapper<T>
boost::ref(T &)'

main.cpp(117): error C2440: 'initializing' : cannot
convert from 'WinMain::my_functor' to
'boost::function2<R,T0,T1>'
        with
        [
            R=void,
            T0=int,
            T1=int
        ]

Change History (5)

comment:1 by Vladimir Prus, 18 years ago

Logged In: YES 
user_id=321498

To begin with, it seems it's boost::ref which fails. I believe this will 
never work, on any compiler, because local classes are not valid 
template arguments. What do you think? 

comment:2 by Douglas Gregor, 18 years ago

Status: assignedclosed
Logged In: YES 
user_id=249098

Vladimir is correct: local classes are not valid template arguments, so it 
is impossible for boost::function (or boost::ref) to support this usage 
(although I wish it could!).

comment:3 by nobody, 18 years ago

Logged In: NO 

Thanks for the swift response and "ouch." :)

I had really been fantisising about local classes being
exactly equivalent to global/namespaced/nested ones. Thanks
again!

John Engstrom

comment:4 by ossmdw45, 18 years ago

Logged In: YES 
user_id=1108669

> Summary: boost::function doesn't accept classes declared
in functions

> This fails to compile, see below for error messages,
> however if I move the declaration of the functor out of
> the function bar(), it compiles fine. Perhaps it only
> happens with MSVC.

No, that's a limitation of C++ templates. Only
classes/structs with external linkage can be used as
template arguments, IIRC. I've heard people talking about
removing this restriction for specifically the reason you're
talking about: to be able to define "lambda" functions
in-scope. But right now it's illegal.

You _can_, however, define it this way (code not compiled
since I'm at work):

void bar()
{
   ...

   struct localfunction
   {
       static void foo(int arg1, int arg2) {
           moo();
       }

       ...
   };
   

   boost::function2<void, int, int> my_function1 =
boost::ref(localfunction::foo);
   boost::function2<void, int, int> my_function2 =
localfunction::foo;
}

This works (should work) because localfunction::foo is just
a regular function pointer (int*int->void), so you can
templatize on it.

comment:5 by nobody, 18 years ago

Logged In: NO 

Yes! Cool technique Max !

With some macros, I was able to make boost::function<>
objects out of my local functors..

John Engstrom

Note: See TracTickets for help on using tickets.