问题描述
我遇到了一些看起来像这样的C ++代码:
void (classA::*methodA)() const noexcept
{
&classA::methodB
};
注意:显然,在此示例中,我正在抽象出类名和方法名。
methodA
的用途是什么?
代码分析
总体看来,它只是在引用address of
方法B。
有关此功能的建议吗?
解决方法
关键信息是您正在使用括号初始化程序语法初始化指向成员函数(PMF)的指针。参见C++ FAQs on PMFs。
以下是示例代码和注释的代码,并提供了一种替代的方式来编写同一件事情,因为它使用类型别名,因此不易混淆:
#include <iostream>
// Declare a class with a non-static method
class classA
{
public:
void methodB() const noexcept { std::cout << "methodB\n"; }
};
int main()
{
// Declare a function pointer by the name of methodA
// and initialize it to point to classA::methodB
void (classA::*methodA)() const noexcept
{
&classA::methodB
};
// Create an instance of classA
const auto a = classA{};
// Call a method on our instance using the function pointer
(a.*methodA)();
////////////////////////////////////////////////////////////////
// A clearer equivalent of the above:
// Declare an alias for the function pointer type
using FnPtr = void (classA::*)() const noexcept;
// Create an instance of the function pointer type,// also using brace initialization and pointing to `classA::methodB`
const auto method = FnPtr{ &classA::methodB };
// Call the function indirectly through the function pointer
(a.*method)();
}
在 Coliru 上实时查看并打印:
methodB
methodB
如果您不需要了解类型(例如,它只是一个局部变量,而不是类的成员),那么一个更短的方法是您可以使用auto
来推断类型:>
const auto someMethod = &classA::methodB;
(a.*someMethod)();
如果您仍然不想键入该别名,但是在无法使用auto
的上下文中需要该别名,则可以使用decltype
进行声明:
// Alias using decltype
using FnPtr = decltype( &classA::methodB );
// Declare instance using decltype (e.g.,as a class member)
decltype( &classA::methodB ) method = nullptr;
// ...
// set it later:
method = &classA::methodB;
// Define template param using decltype
auto fnPtrs = std::vector< decltype( &classA::methodB ) >{};
,
有关此功能的建议吗?
它正在定义一个名为methodA
的变量,并将其初始化为&classA::methodB
。
变量的类型是
指向const
的{{1}}成员函数的指针,该指针不带任何参数,返回classA
,并且该成员函数不会引发任何异常。
变量已初始化为void
。
如果将其设置为单线,则为:
&classA::methodB
等效于:
void (classA::*methodA)() const noexcept {&classA::methodB};