如何获取函数中定义的本地类的成员函数的地址(C ++)

时间:2010-01-28 07:05:06

标签: c++ member-function-pointers local-class

我正在尝试执行以下操作:从函数中本地定义的类中获取成员函数的地址。

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);

    }
};

尝试#2和#3完全混淆GCC,它不知道我想做什么。 尝试#1产生一个更有用的错误消息,说没有setupCallback存在,其格式为“setupCallback(void(SomeUnitTest :: someTest():: NestedClass :: SomeFunction :: *)等) 试试#3是如何诞生的。

我无法真正找到关于函数内定义的类的大量信息,是否有人知道正确的语法,并且可能有一个讨论该主题的资源?

好吧,看来这已经解决了,因为两个海报都指出,本地班级没有联系,也无法奏效。现在知道了这一点,我发现这篇文章讨论了这个问题,对于遇到这个问题的任何其他人都会遇到这个问题:http://www.informit.com/guides/content.aspx?g=cplusplus&seqNum=420

编辑: 澄清setupCallback(),使用更常规的类的工作示例 编辑#2: 更新了措辞以将“嵌套”更改为“本地”。添加了setupCallback的更多细节 编辑#3:添加了更多信息的链接。感谢大家。

2 个答案:

答案 0 :(得分:4)

我不知道语法问题,通常的访问规则应该适用 - 但是如果这些成功,因为这些成员函数没有链接,这里还有另一个问题。
要接受本地类型,setupCallback()必须是模板函数 - 但不允许没有链接的模板类型参数。

§3.5/ 8 说:

  

这些规则未涵盖的名称有   没有联系。此外,除非另有说明,   在本地范围内声明的名称   (3.3.2)没有联系。

当地班级的成员不在那里。 §9.3/ 3 澄清:

  

本地班级的成员职能   (9.8)没有联系。

长篇摘要:不要使用本地类的成员函数作为回调,而是使用非本地类。

答案 1 :(得分:4)

只要考虑到地址的具体问题,你的拳头变体是正确的。获取本地类的成员函数的地址没有限制。正常的语法是通常的

&NestedClass::someFunction

这就是它。您可以尝试将其保存在代码中的中间指针

void (NestedClass::*ptr)() = &NestedClass::someFunction;

我确信你的编译器会接受它。

然而,我怀疑你的代码中存在的问题与获取成员函数地址的正确方法完全无关。它更像是声明setupCallback的第一个参数的方式。既然你说它是&SomeClass::someFunction作为第一个参数,我希望setupCallback被声明为

void setupCallback(void (SomeClass::*cb)(), SomeClass *p); // one possibility

即。它是硬编码的以期望指向SomeClass成员的指针。您无法提供指向NestedClass成员的指针。 NestedClassSomeClass完全无关,指向NestedClass成员的指针与指向SomeClass成员的指针完全不兼容。这就是为什么它不会编译。

除非有什么东西你没有向我们展示(比如setupCallback可能是一个功能模板?或者是因为不同的参数类型而超负荷?),无论你怎么做,你想要做的事情根本无法实现会员地址,只要NestedClassSomeClass无关。功能setupCallback旨在仅与SomeClassSomeClass一起使用。

提供有关setupCallback的更多信息。怎么声明?

请注意,如果setupCallback被声明为按类类型参数化的函数模板,如

template <class T> void setupCallback(void (T::*cb)(), T* p);

然后您将无法使用本地类NestedClass作为参数T的模板参数。在这种情况下,你的NestedClass没有联系的事实确实发挥了作用。但是,它再次与获取成员地址无关,而是由于没有链接的类不能用作C ++中的模板参数这一事实。