Search code examples
c++pointer-to-memberlocal-class

How to get address of member function for local class defined in function (C++)


I am trying to do the following: Obtain the address of a member function from a class that was locally defined within a function.

class ConnectionBase
{
};

template class<EventType, SinkType>
class ConnectionImpl : public ConnectionBase
{
public:
typedef void (SinkType::*EventCallback)(EventType const&);
};


template<class EventType>
class Source
{
    template <class SinkType>
    boost::shared_ptr<ConnectionBase> setupCallback(typename ConnectionImpl<EventType, SinkType>::EventCallback func, SinkType* sink)
    {
    // do the actual connecting.
    }
};

class SomeClass
{
public:
    void someFunction(int const& event){}
}

class SomeUnitTest
{
public:
    void someTest()
    {
        class NestedClass 
        {
        public:
            void someFunction(int const& event){}
        };

       NestedClass nc;

       //Try#1 - This does not work
       setupCallback<int, NestedClass>(&NestedClass::someFunction, &nc);

       //Try #2 - This also does not work
       setupCallback<int, NestedClass>(&SomeUnitTest::someTest::NestedClass::someFunction, &nc);

       //Try #3 - Following the GCC error output, I tried this
       setupCallback<int, NestedClass>(&SomeUnitTest::someTest()::NestedClass::someFunction, &nc);

       SomeClass sc;

       //This works fine, as expected
       setupCallback<int, SomeClass>(&SomeClass::someFunction, &sc);

    }
};

Try #2 and #3 utterly confuse GCC, it has no idea what I am trying to do. Try #1 produces a more helpful error message saying no setupCallback exists that takes the form "setupCallback(void (SomeUnitTest::someTest()::NestedClass::SomeFunction::*), etc) Which is how try #3 was born.

I can't really find a lot of information about classes defined inside a function, does anyone know the correct syntax for this, and maybe have a resource that discusses this topic?

Ok, it appears this is settled, as both posters have pointed out, local classes have no linkage, it can't work. Now knowing this, I found this article that discusses this, for anyone else that runs into this problem and stumbles across this question: http://www.informit.com/guides/content.aspx?g=cplusplus&seqNum=420

Edit: Clarification of setupCallback(), working example with a more regular class
Edit #2: Updated wording to change "nested" to "local". Added more detail for setupCallback.
Edit #3: Added links to furhter information. Thanks everyone.


Solution

  • I don't know about the syntax problem, the usual access rules should apply - but there is another problem here if that would work as these member functions have no linkage.
    To accept local types at all, setupCallback() would have to be a template function - but template type arguments with no linkage are not allowed.

    §3.5/8 says:

    Names not covered by these rules have no linkage. Moreover, except as noted, a name declared in a local scope (3.3.2) has no linkage.

    Members of local classes are not covered there. §9.3/3 clarifies that:

    Member functions of a local class (9.8) have no linkage.

    Long story cut short: don't use member functions of a local class as callbacks, use a non-local class instead.