En C ++ qu'est-ce que cela signifie pour un compilateur à « en ligne » un objet de fonction?

StackOverflow https://stackoverflow.com/questions/2225643

  •  19-09-2019
  •  | 
  •  

Question

Dans le wikipedia article sur les objets fonction il dit de tels objets ont des avantages de performance lorsqu'ils sont utilisés avec for_each parce que le compilateur peut « en ligne » les.

Je suis un peu brumeuse exactement ce que cela signifie dans ce contexte ... ou tout contexte, je suis gêné de dire. Merci pour toute aide!

Était-ce utile?

La solution

Le dernier paramètre du modèle de for_each est foncteur . Functor est quelque chose qui peut être "appelé" à l'aide de l'opérateur () (éventuellement avec des arguments). Par défintion, il existe deux types distincts de foncteurs:

  1. ordinaires fonctions non-membres sont foncteurs.
  2. Les objets de type classe avec l'opérateur () surchargée (appelé fonction des objets ) sont également foncteurs.

Maintenant, si vous voulez utiliser une fonction ordinaire comme foncteur pour for_each, il ressemblerait à quelque chose comme ce qui suit

inline void do_something(int &i) { /* do something */ }

int main() {
  int array[10];
  std::for_each(array, array + 10, &do_something);
}

Dans ce cas, le modèle de for_each est instancié avec des arguments [déduit] <int *, void (*)(int &)>. Notez que la valeur réelle de foncteur dans ce cas est le pointeur de fonction &do_something passé comme argument de la fonction. Du point de vue de la fonction for_each ceci est une valeur d'exécution. Et comme il est une valeur d'exécution, les appels à la foncteur ne peuvent pas être inline. (Tout comme il est dans le cas général, impossible de inline tout appel effectué par un pointeur de fonction).

Mais si l'on utilise un objet de fonction à la place, le code peut se présenter comme suit

struct do_something {
  void operator()(int &i) { /* do something */ }
}; 

int main() {
  int array[10];
  std::for_each(array, array + 10, do_something());
}

Dans ce cas, le modèle de for_each est instancié avec des arguments [déduit] <int *, do_something>. Les appels à la foncteur à l'intérieur for_each seront dirigés vers do_something::operator(). L'objectif de l'appel est connu et fixé à la compilation. Étant donné que la fonction cible est connue à la compilation, l'appel peut facilement être mise en ligne.

Dans ce dernier cas, nous, bien sûr, ont aussi une valeur d'exécution passé comme argument à for_each. Il est une instance de la classe do_something [peut-être temporaire « factice »] nous créons quand nous appelons for_each. Mais cette valeur d'exécution n'a pas d'effet sur la cible de l'appel (à moins que le operator () est virtuel), de sorte qu'il ne touche pas inline.

Autres conseils

Inline est le processus d'un compilateur peut remplacer un appel à une fonction avec le contenu de la fonction elle-même. Il nécessite le compilateur de connaître le contenu de la fonction quand il est en cours d'élaboration.

Le compilateur ne peut souvent pas faire si un pointeur de fonction est passée.

Inlining signifie simplement le remplacement de chaque appel à cette fonction avec le corps de cette fonction directement.

Il est une optimisation pour les petites fonctions, car il réduit les frais généraux de saut à une nouvelle fonction, puis revenir.

Cela signifie que la définition de la fonction (code) peut être copié et vous évite d'un appel de fonction (ce qui est considéré comme cher sur certains systèmes). Pensez à remplacer macro.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top