Deducción de la función


Digamos que tenemos una plantilla de clase como esta:

template<typename F>
class A
{
public:
  template<typename... Args>
  A(F f, Args... args)
  { /* Do something... */ }
};

Y ahora quiero usarlo de alguna manera como este:

A<int(int)> a(::close, 1);

Ahora la pregunta: ¿hay alguna manera de omitir el <int(int)> porque un compilador puede conocer esta información para el ::close? No hay necesidad de guardar el "diseño" de la plantilla.

En cuanto a la tarea concreta, necesito diseñar una plantilla de una clase. Los objetos de esta clase podrían tomar una función y parámetros para esta función en tiempo de construcción y llamar a esto función más tarde.

Author: Serge Roussak, 2016-07-06

3 answers

No, usted (actualmente) no puede. La forma estándar de hacer esto es creando la función" make_like " (como make_pair, make_optional ...):

template<typename F, typename... Args>
A<std::decay_t<F>> make_A (F &&f, Args&&... args) {
    return {std::forward<F>(f), std::forward<Args>(args)...};
}

C++17 introducirá deducción de argumento de plantilla para la clase que le permitirá hacer exactamente lo que desee.

 35
Author: Holt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-07-06 18:38:15

Gracias a la adopción de la deducción de parámetros de plantilla para constructores, en C++17, usted será capaz de escribir:

A a(::close, 1);

Antes de eso, solo tendrá que escribir una fábrica para hacer la deducción por usted:

template <class F, class... Args>
A<std::decay_t<F>> make_a(F&& f, Args&&... args) {
    return {std::forward<F>(f), std::forward<Args>(args)...};
}

auto a = make_a(::close, 1);

Esto es un poco detallado, pero al menos no necesita preocuparse por la eficiencia: no se harán copias aquí gracias a RVO.

 16
Author: Barry,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-07-07 11:38:35

No puede omitir los argumentos de una clase de plantilla, a menos que estén predeterminados. Lo que puede hacer es tener una función maker que deduce el argumento y reenvía este argumento a la clase template, devolviendo un objeto de la instanciación apropiada.

template<typename F, typename... Args>
A<F> make_A(F f, Args&&... args) {
    return A<F>(f, std::forward<Args>(args)...);
}
 11
Author: Benjamin Lindley,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-07-06 16:12:31