给定
struct A {
int foo(double a, std::string& b) const;
};
我可以像这样创建一个成员函数指针:
typedef int (A::*PFN_FOO)(double, std::string&) const;
很简单,除了如果's 的签名发生变化PFN_FOO
需要更新。A::foo
既然C++11引入了decltype
,能不能用来自动推导出签名,创建typedef呢?
是的当然:
typedef decltype(&A::foo) PFN_FOO;
您还可以通过using
关键字定义类型别名(感谢 Matthieu M.):
using PFN_FOO = decltype(&A::foo);
一个问题:如果这个变量是明确的,你只能推断出一个变量的类型。
函数的主要问题是重载意味着仅靠它们的名称不足以识别它们。因此,decltype
如果您引入foo
in的重载,使用失败A
。
struct A {
void foo() const;
void foo(int) const;
};
using PFN_FOO = decltype(A::foo);
source.cpp:6:36: error: decltype cannot resolve address of overloaded function
不确定你会因此获得很多...
另一方面,您实际上可以使用别名并检查别名是否正确:
struct A {
void foo() const;
void foo(int) const;
};
using PFN_FOO = void (A::*)(int) const;
static_assert(std::is_same<PFN_FOO, decltype(static_cast<PFN_FOO>(&A::foo))>::value,
"Ooops, need to update signature of PFN_FOO!");
注意:不确定这是最好的测试方法,基本上你只需要static_cast
零件,我只是想在旁边隐藏一条错误消息。不过,您可能需要像 SFINAE 这样的东西来获得更好的消息。