我正在尝试执行以下操作:从函数中本地定义的类中获取成员函数的地址。
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:添加了更多信息的链接。感谢大家。
答案 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
成员的指针。 NestedClass
与SomeClass
完全无关,指向NestedClass
成员的指针与指向SomeClass
成员的指针完全不兼容。这就是为什么它不会编译。
除非有什么东西你没有向我们展示(比如setupCallback
可能是一个功能模板?或者是因为不同的参数类型而超负荷?),无论你怎么做,你想要做的事情根本无法实现会员地址,只要NestedClass
与SomeClass
无关。功能setupCallback
旨在仅与SomeClass
和SomeClass
一起使用。
提供有关setupCallback
的更多信息。怎么声明?
请注意,如果setupCallback
被声明为按类类型参数化的函数模板,如
template <class T> void setupCallback(void (T::*cb)(), T* p);
然后您将无法使用本地类NestedClass
作为参数T
的模板参数。在这种情况下,你的NestedClass
没有联系的事实确实发挥了作用。但是,它再次与获取成员地址无关,而是由于没有链接的类不能用作C ++中的模板参数这一事实。