函数成员指针:`R(*C::*)(Args...)` 是什么意思?

17

考虑以下代码:

template <class>
struct test: std::integral_constant<int, 0> {};
template<class R, class C, class... Args>
struct test<R(C::*)(Args...)>: std::integral_constant<int, 1> {};
template<class R, class C, class... Args>
struct test<R(*C::*)(Args...)>: std::integral_constant<int, 2> {};
template<class R, class C, class... Args>
struct test<R(**C::*)(Args...)>: std::integral_constant<int, 3> {};
template<class R, class C, class... Args>
struct test<R(C::**)(Args...)>: std::integral_constant<int, 4> {};
template<class R, class C, class... Args>
struct test<R(C::***)(Args...)>: std::integral_constant<int, 5> {};

我完全不知道(*C::*)(**C::*)(C::**)(C::***)的含义。 我想要一个test<decltype(f)>的示例,其value将等于2345。 另外,在这种情况下,如何使用f的语法调用成员函数?

1个回答

18

考虑这个例子

struct s {
    void test1();
    void(*test2)();
    void(**test3)();
};

int main() {
    static_assert(test<decltype(&s::test1)>::value == 1);   
    static_assert(test<decltype(&s::test2)>::value == 2);   
    static_assert(test<decltype(&s::test3)>::value == 3);   

    auto test4 = &s::test1;
    static_assert(test<decltype(&test4)>::value == 4);   

    auto test5 = &test4;
    static_assert(test<decltype(&test5)>::value == 5);   
}

这里是类型:

R(C::*)(Args...) - 成员函数指针。
R(*C::*)(Args...) - 数据成员指向函数指针的指针。
R(**C::*)(Args...) - 数据成员指向函数指针指针的指针。
R(C::**)(Args...) - 指向成员函数指针的指针。
R(C::***)(Args...) - 指向成员函数指针指针的指针。

要调用这些类型,请考虑一个稍微修改过的示例

struct s {
    void test1() {std::cout << "test1\n";}
    void(*test2)() = [] {std::cout << "test2\n";};

    void(*test3Helper)() = [] {std::cout << "test3\n";};
    void(**test3)() = &test3Helper;

    void test4() {std::cout << "test4\n";}
    void test5() {std::cout << "test5\n";}
};

int main() {
    s obj;  

    auto test4 = &s::test4;

    auto test5Helper = &s::test5;
    auto test5 = &test5Helper;  

    (obj.*(&s::test1))();
    (*(obj.*(&s::test2)))(); // note that the dereference is unnecessary
    (**(obj.*(&s::test3)))(); // note that the second dereference is unnecessary
    (obj.**(&test4))();
    (obj.***(&test5))();
}

请注意,在每种情况下,如果您有一个值为适当&[s::]testN的变量,您可以将(&[s::]testN)替换为该变量。同时注意,在test2和test3中,我进行了取消引用直到获取函数而不是函数指针的操作,这仅用于说明目的。


谢谢!如果s有一个函数成员int f(int x) {return x;},并且testN引用它,那么在变量上执行testN的语法是什么? - Vincent
@Vincent,我马上就到。等一下。 - chris

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接