L'appel de fonction de modèle sans <>; l'inférence de type
Si j'ai un modèle de fonction avec typename T
, où le compilateur peut définir le type en lui-même, je n'ai pas à écrire le type de manière explicite lorsque j'appelle la fonction comme:
template < typename T >
T min( T v1, T v2 ) {
return ( v1 < v2 ) ? v1: v2;
}
int i1 = 1, i2 = 2; int i3 = min( i1, i2 ); //no explicit <type>
Mais si j'ai un modèle de fonction avec deux typenames comme:
template < typename TOut, typename TIn >
TOut round( TIn v ) {
return (TOut)( v + 0.5 );
}
double d = 1.54;
int i = round<int>(d); //explicit <int>
Est-il vrai que j'ai toujours spécifier au moins 1 typename? Je suppose que la raison est parce que le C++ ne peut pas distinguer les fonctions entre les différents types de retour.
Mais si j'utilise une fonction void et la remise d'une référence, encore une fois je ne doit pas spécifier explicitement le retour typename:
template < typename TOut, typename TIn >
void round( TOut & vret, TIn vin ) {
vret = (TOut)(vin + 0.5);
}
double d = 1.54;
int i; round(i, d); //no explicit <int>
Si la conclusion est d'éviter de fonctions avec le retour et la plus préfèrent void
fonctions qui renvoient par l'intermédiaire d'une référence lors de l'écriture de modèles? Ou est-il une possibilité pour éviter écrivant explicitement le type de retour? Quelque chose comme "l'inférence de type" pour les modèles. Est "l'inférence de type" possible en C++0x?
Vous pourriez vouloir travailler sur votre algorithme arrondi. Ce qui devrait -1.54 en sortir? Et: que faire si vous voulez obtenir un arrondi double de la valeur?
OriginalL'auteur OlimilOops | 2010-05-14
Vous devez vous connecter pour publier un commentaire.
Résolution de surcharge se fait uniquement basée sur des arguments de la fonction; la valeur de retour n'est pas utilisée du tout. Si le type de retour ne peut pas être déterminée sur la base des arguments, vous devrez le spécifier explicitement.
Je n'irais pas sur le chemin du retour" d'une valeur via un paramètre de référence; qui rend le code d'appel clair. Par exemple, je préfère ceci:
au cours de cette:
parce que dans le dernier cas, il est facile de confondre l'entrée et la sortie, et il n'est pas clair du tout que
x
est en cours de modification.Dans le cas particulier de
round
, vous avez probablement besoin de seulement un ou deux types deTOut
de toute façon, alors vous pouvez simplement laisser que l'argument de modèle:Je trouve
roundToInt(x)
un peu plus clair queround<int>(x)
parce qu'il est clair que laint
type est utilisé pour.round_to<int>(x)
? 😉Yep, ça pourrait être sympa aussi.
OriginalL'auteur Thomas
Non, pourquoi? Que gagnez-vous? Seulement l'inférence de type (donc moins de code à écrire). Mais vous perdre beaucoup plus logique de la syntaxe de l'attribution d'une valeur (et, par conséquent, plus de code à écrire). Donc, une chose acquise, une autre a perdu. Je ne vois pas l'intérêt en général.
Il peut même aider d'avoir à spécifier le type de modèle explicitement: prenons le cas de
lexical_cast
. En ne spécifiant pas le retour type de modèle serait source de confusion.OriginalL'auteur Konrad Rudolph
Permettez-moi d'ajouter à ce que les autres ont dit en disant que vous devriez préférer C++ casting sur C-style casting.
contre
statique plâtre sera toujours voués à l'échec si vous essayez de convertir sans rapport avec les types. Cela peut être utile pour le débogage.
Quelles seraient les types qui y participent doivent être, de sorte qu'un
static_cast
donnerait un résultat différent de celui d'une C-style coulé dans ce modèle? (Oui, dans une fonction d'utilité que vous pourriez faire des efforts pour améliorer son style, mais je ne vois pas beaucoup d'avantages dans la pure mathématique du code de la conversion entre les types de numéro - pour justifier un post, et peut-être pas un commentaire.)Vous pouvez peut-être sur ce post, mais j'ai eu à carillon. Si vous utilisez un
static_cast
, un message d'erreur signifie que l'objet ou exécutable ne peut même pas exister, alors la réciproque est vraie, c'est, si vous avez un objet ou exécutable, vous savez que lestatic_cast
était valable entre les types. Comme vous aller plus loin dans le modèle de la métaprogrammation, vous aurez besoin de plus de contrôle sur les types à l'intérieur de leur héritage arbres, par exemple, dans le PFI.OriginalL'auteur wheaties