c++ - Puntero a los miembros de la función: ¿qué significa `R(* C::*)(Args...)`?
c++11 member-function-pointers (1)
Considera este ejemplo :
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);
}
Aquí están los tipos:
R(C::*)(Args...)
- Un puntero a una función miembro.
R(*C::*)(Args...)
- Un puntero a un miembro de datos que es un puntero a función.
R(**C::*)(Args...)
- Un puntero a un miembro de datos que es un puntero a un puntero de función.
R(C::**)(Args...)
- Un puntero a un puntero a una función miembro.
R(C::***)(Args...)
- Un puntero a un puntero a un puntero a una función miembro.
Para llamar a estos, considere un ejemplo ligeramente modificado :
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))();
}
Tenga en cuenta que en cada caso, si tiene una variable con el valor de la &[s::]testN
apropiada de &[s::]testN
, puede reemplazar (&[s::]testN)
con esa variable. Tenga en cuenta también que para las pruebas test2 y test3, hice una referencia previa hasta que se recuperó la función en lugar del puntero de la función con fines ilustrativos.
Considere el siguiente código:
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> {};
No tengo la menor idea de lo que significan (*C::*)
, (**C::*)
, (C::**)
y (C::***)
. Me gustaría un ejemplo de una test<decltype(f)>
cuyo value
sería igual a 2
, 3
, 4
y 5
. Además, en ese caso, ¿cómo es la sintaxis para f
que llamaría a la función miembro?