34

给定

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呢?

4

2 回答 2

56

是的当然:

typedef decltype(&A::foo) PFN_FOO;

您还可以通过using关键字定义类型别名(感谢 Matthieu M.):

using PFN_FOO = decltype(&A::foo);

于 2012-10-26T14:50:42.620 回答
23

一个问题:如果这个变量是明确的,你只能推断出一个变量的类型。

函数的主要问题是重载意味着仅靠它们的名称不足以识别它们。因此,decltype如果您引入fooin的重载,使用失败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 这样的东西来获得更好的消息。

于 2012-10-26T17:29:48.110 回答