c++ - sirven - punteros void lenguaje c
puntero a la función miembro en la expresión de plegado (1)
Este código llama & foo :: siguiente varias veces
struct foo
{
foo& next()
{
return *this;
}
};
template<typename Obj>
void tmp_funct_1(Obj& obj)
{}
template<typename Obj, typename Func, typename... Other>
void tmp_funct_1(Obj& obj, Func func, Other... other)
{
tmp_funct_1((obj.*func)(), other...);
}
Ahora quiero reemplazar las llamadas recursivas con una expresión doble
Ejemplo:
template<typename Obj, typename... Func>
void tmp_funct_2(Obj& obj, Func... func)
{
(obj .* ... .* func());
}
No se compila porque la sintaxis correcta para el puntero a la llamada de miembro es
(obj.*func)()
¿Cómo puedo lograr el mismo resultado utilizando la expresión de plegado de plantilla? ¡Gracias!
int main()
{
foo obj;
auto to_foo = &foo::next;
tmp_funct_1(obj, to_foo, to_foo, to_foo);
// tmp_funct_2(obj, to_foo, to_foo, to_foo);
}
El siguiente código funciona para un solo argumento, pero no para varios:
template<typename Obj, typename... Func>
void tmp_funct_2(Obj& obj, Func... func)
{
(obj .* ... .* func)();
}
int main()
{
foo obj;
auto to_foo = &foo::next;
tmp_funct_2(obj, to_foo);
}
El problema es que la expresión de plegado no se expande a una invocación anidada de los punteros de función como ...
(((((obj.*to_foo)().*to_foo)()).*to_foo)());
... pero más bien se expande a algo como ...
obj.*func0.*func1.*func2.*func3
... que no es lo que quieres.
A menos que sobrecargue el operator.*
, Creo que está atascado con el enfoque recursivo aquí. De lo contrario, puede utilizar un almacenamiento temporal y plegar el operador de coma:
template<typename Obj, typename... Func>
void tmp_funct_2(Obj& obj, Func... func)
{
auto* temp = &obj;
((temp = &((*temp).*func)()), ...);
}