32 votes

Déduction de la fonction

Disons que nous avons un modèle de classe comme ceci:

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

Et maintenant je veux l'utiliser en quelque sorte, comme celui-ci:

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

Maintenant, la question: est-il possible d'omettre l' <int(int)> parce qu'un compilateur peut connaître cette information pour l' ::close? Il n'est pas nécessaire d'enregistrer le "design" du modèle.

Comme pour la tâche concrète, j'ai besoin de concevoir un modèle de classe. Des objets de cette classe pourrait prendre une fonction et les paramètres de cette fonction au moment de la construction et de l'appel de cette fonction plus tard.

35voto

Holt Points 6689

Non, vous (actuellement) ne le peuvent pas. Le standard de la façon de le faire est par la création de "make_like" fonction (comme 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 présentera argument de modèle déduction pour la classe qui vous permettra de faire exactement ce que vous voulez.

16voto

Barry Points 45207

Grâce à l'adoption de la déduction des paramètres de modèle pour les constructeurs, en C ++ 17, vous pourrez simplement écrire:

 A a(::close, 1);
 

Avant cela, il vous suffit de créer une usine pour effectuer la déduction à votre place:

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

C'est un peu bavard, mais au moins vous n'avez pas à vous soucier de l'efficacité, il n'y aura pas de copies réalisées ici grâce à RVO.

11voto

Benjamin Lindley Points 51005

Vous ne pouvez pas omettre les arguments d'une classe de modèle, à moins qu'ils ne soient définis par défaut. Ce que vous pouvez faire, c'est une fonction maker qui déduit l'argument et le transmet à la classe de modèle, en renvoyant un objet de l'instanciation appropriée.

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X