web-dev-qa-db-fra.com

Est-il logique d'utiliser un mot-clé en ligne avec des modèles?

Étant donné que les modèles sont définis dans les en-têtes et que le compilateur est en mesure de déterminer si l’inclusion d’une fonction est avantageuse, cela a-t-il un sens? J'ai entendu dire que les compilateurs modernes savent mieux quand insérer une fonction en ligne et ignorent inline hint.


edit: Je voudrais accepter les deux réponses, mais ce n'est pas possible. Pour clore la question, j'accepte la réponse de phresnel, car elle a reçu le plus grand nombre de votes et il a officiellement raison, mais comme je l'ai mentionné dans des commentaires, j'estime que Puppy et - Composant 1 les réponses sont également correctes, sous des angles différents.

Le problème est dans la sémantique C++, qui n'est pas stricte dans le cas de inline mot-clé et inlining. phresnel dit "écris en ligne si tu le penses", mais ce que l'on entend en réalité par inline n'est pas clair car il est passé de son sens initial à une directive qui "arrête les reproches des compilateurs à propos de l'ODR violations "comme chiot dit.

103
doc

Ce n'est pas sans importance. Et non, tous les modèles de fonction ne sont pas inline par défaut. La norme est même explicite à ce sujet dans Spécialisation explicite ([temp.expl.spec])

Avoir les éléments suivants:

a.cc

#include "tpl.h"

b.cc

#include "tpl.h"

tpl.h (tiré de la spécialisation explicite):

#ifndef TPL_H
#define TPL_H
template<class T> void f(T) {}
template<class T> inline T g(T) {}

template<> inline void f<>(int) {} // OK: inline
template<> int g<>(int) {} // error: not inline
#endif

Compilez ceci, et le tour est joué:

g++ a.cc b.cc
/tmp/ccfWLeDX.o: In function `int g<int>(int)':
inlinexx2.cc:(.text+0x0): multiple definition of `int g<int>(int)'
/tmp/ccUa4K20.o:inlinexx.cc:(.text+0x0): first defined here
collect2: ld returned 1 exit status

Ne pas indiquer inline lors de l'instanciation explicite peut également entraîner des problèmes.

Donc en résumé : Pour les modèles de fonction non totalement spécialisés, c'est-à-dire ceux qui portent au moins un type inconnu, vous pouvez omettre inline, et pas recevoir les erreurs, mais ils ne sont toujours pas inline. Pour les spécialisations complètes, c'est-à-dire celles qui utilisent uniquement des types connus, vous ne pouvez pas l'omettre.

Proposition de règle générale : Écrivez inline si vous le voulez bien et soyez juste cohérent. Cela vous fait moins penser à si ou pas juste parce que vous le pouvez. (Cette règle empirique est conforme à Vandevoorde/Josuttis Modèle C++: le guide complet ).

87
Sebastian Mach

Ce n'est pas pertinent. Tous les modèles sont déjà inline- sans oublier qu'à partir de 2012, le mot-clé inline ne sera utilisé que pour empêcher les compilateurs de se plaindre des violations des règles ODR. Vous avez tout à fait raison: votre compilateur de génération actuelle saura quoi utiliser en ligne et le fera probablement même entre unités de traduction.

27
Puppy

Comme vous l'avez suggéré, inline est un indice pour le compilateur et rien de plus. Il peut choisir de l'ignorer ou, en fait, de fonctions en ligne non marquées en ligne.

Utiliser inline avec des modèles était un moyen (médiocre) de contourner le problème selon lequel chaque unité de compilation créerait un objet séparé pour la même classe basée sur un modèle, ce qui causerait des problèmes de duplication au moment du lien. En utilisant inline (je pense), le nom mangling fonctionne différemment, ce qui évite les conflits de noms au moment de la liaison, mais au détriment d'un code extrêmement saturé.

Marshall Cline explique ici mieux que moi.

1
Component 10