如何获取函数中定义的本地类的成员函数的地址(C++)
我正在尝试执行以下操作:从函数中本地定义的类获取成员函数的地址。
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::*), etc) 这就是尝试#3 的诞生。
我真的找不到关于函数内定义的类的大量信息,有人知道正确的语法吗?也许有讨论这个主题的资源?
好吧,看来这已经解决了,正如两位海报所指出的那样,本地类没有链接,它无法工作。现在知道了这一点,我发现这篇文章讨论了这个问题,对于遇到这个问题并偶然发现这个问题的其他人: http://www.informit.com/guides/content.aspx?g=cplusplus&seqNum=420
编辑: setupCallback() 的说明,使用更常规的类的工作示例
编辑#2: 更新了措辞,将“嵌套”更改为“本地”。添加了 setupCallback 的更多详细信息。
编辑#3:添加了更多信息的链接。谢谢大家。
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我不知道语法问题,通常的访问规则应该适用 - 但这里还有另一个问题,如果这可以工作,因为这些成员函数没有链接。
要完全接受本地类型,setupCallback() 必须是模板函数 - 但不允许没有链接的模板类型参数。
§3.5/8 说:
当地班级的成员不包括在内。 §9.3/3 澄清:
长话短说:不要使用本地类的成员函数作为回调,而是使用非本地类。
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:
Members of local classes are not covered there. §9.3/3 clarifies that:
Long story cut short: don't use member functions of a local class as callbacks, use a non-local class instead.
只要考虑获取地址的具体问题,您的第一个变体就是正确的。获取本地类的成员函数的地址没有任何限制。正确的语法是通常的语法
,仅此而已。您可以尝试将其保存在代码中的中间指针中
,我确信您的编译器会接受它。
但是,我怀疑您的代码中存在的问题与获取成员函数地址的正确方法绝对无关。它与声明setupCallback 的第一个参数的方式有关。既然你说它可以使用
&SomeClass::someFunction
作为第一个参数,我希望setupCallback
被声明为,即它是硬编码的 期望有一个专门指向
SomeClass
成员的指针。您不能提供指向NestedClass
成员的指针。NestedClass
与SomeClass
完全无关,并且指向NestedClass
成员的指针与指向SomeClass
成员的指针完全不兼容。这就是它无法编译的原因。除非有一些东西你没有向我们展示(比如 setupCallback 可能是一个函数模板?或者针对不同的参数类型进行重载?),否则无论你如何采取,你想要做的事情都是不可能实现的成员地址,只要
NestedClass
与SomeClass
保持无关。函数setupCallback
设计为仅与SomeClass
和SomeClass
一起使用。提供有关
setupCallback
的更多信息。它是如何声明的?请注意,如果
setupCallback
被声明为按类类型参数化的函数模板,那么您将无法使用本地类
NestedClass
作为参数的模板参数T
。在这种情况下,您的NestedClass
没有链接这一事实确实发挥了作用。但是,同样,它与获取成员地址无关,而是由没有链接的类不能用作 C++ 中的模板参数这一事实引起的。You fist variant is the correct one as long as the specific matter of taking the address is considered. There are no restrictions on taking the address of member functions of local classes. The proper syntax is the usual
ans that's it. You can try saving it in an intermediate pointer in your code
and I'm sure your compiler will accept it.
However, the problem I suspect exists in your code has absolutely nothing to do with the proper way of taking the address of a member function. It is rather about the way the first parameter of
setupCallback
is declared. Since you say it works with&SomeClass::someFunction
as the first argument, I'd expectsetupCallback
to be declared asi.e. it is hardcoded to expect a pointer to a member of
SomeClass
specifically. You cannot supply a pointer to a member ofNestedClass
instead.NestedClass
is completely unrelated toSomeClass
and pointers to members ofNestedClass
are completely incompatible with pointers to members ofSomeClass
. This is why it won't compile.Unless there's something you are not showing us (like
setupCallback
being a function template maybe? Or overloaded for different parameter types?), what you are trying to do is simply impossible to achieve regardless of how you take the member address, as long asNestedClass
remains unrelated toSomeClass
. FunctionsetupCallback
is designed to work withSomeClass
andSomeClass
only.Provide more information about
setupCallback
. How is it declared?Note that if the
setupCallback
is declared as a function template parametrized by class type, as inthen you won't be able to use the local class
NestedClass
as template argument for parameterT
. In this case the fact that yourNestedClass
has no linkage does indeed come into play. But, again, it has nothing to do with taking the member address, but rather caused by the fact that classes with no linkage cannot be used as template arguments in C++.