Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pointer to function members: what does `R(*C::*)(Args...)` mean?

Consider the following code:

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> {};

I have absolutely no idea of what (*C::*), (**C::*), (C::**) and (C::***) mean. I would like an example of a test<decltype(f)> whose value would be equal to 2, 3, 4 and 5. Plus, in that case, how is the syntax for f that would call the member function?

like image 289
Vincent Avatar asked Dec 02 '15 05:12

Vincent


People also ask

What does a pointer to a function point to?

A pointer to a function points to the address of the executable code of the function. You can use pointers to call functions and to pass functions as arguments to other functions.

What is pointer to a function explain with example?

In C, like normal data pointers (int *, char *, etc), we can have pointers to functions. Following is a simple example that shows declaration and function call using function pointer. #include <stdio.h> // A normal function with an int parameter. // and void return type.

How do you declare a pointer to a member function in C++?

The pointer to member operators . * and ->* are used to bind a pointer to a member of a specific class object. Because the precedence of () (function call operator) is higher than . * and ->* , you must use parentheses to call the function pointed to by ptf .

Why do we use pointers to functions in C?

Function pointers in C can be used to create function calls to which they point. This allows programmers to pass them to functions as arguments. Such functions passed as an argument to other functions are also called callback functions.


1 Answers

Consider this example:

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);   
}

Here are the types:

R(C::*)(Args...) - A pointer to a member function.
R(*C::*)(Args...) - A pointer to a data member that is a function pointer.
R(**C::*)(Args...) - A pointer to a data member that is a pointer to a function pointer.
R(C::**)(Args...) - A pointer to a pointer to a member function.
R(C::***)(Args...) - A pointer to a pointer to a pointer to a member function.

To call these, consider a slightly modified example:

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))();
}

Note that in each case, if you have a variable with the value of the appropriate &[s::]testN, you can replace (&[s::]testN) with that variable. Note also that for test2 and test3, I dereferenced until getting the function back rather than the function pointer for illustration purposes.

like image 114
chris Avatar answered Sep 17 '22 17:09

chris