2016-03-02 1 views
1

Je suis relativement nouveau à C++. Je viens de lire sur le mot-clé auto en ce qui concerne la déduction de type. J'ai essayé d'implémenter ceci dans quelques fonctions seulement pour trouver que cela causait toutes sortes de problèmes en travaillant avec des opérateurs de maths. Je crois que ce qui se passait était que mes fonctions commençaient à implémenter la division entière quand j'avais réellement besoin de la division float (variables 'i' et 'avg'). J'ai posté le code en utilisant les mots-clés automatiques ci-dessous.C++ Mot-clé Auto - Flottant vs Int Problème

Maintenant, quand j'ai explicitement déclaré les variables comme des flottants, la fonction a bien fonctionné.

Donc, est-ce un exemple dans lequel l'utilisation d'auto ne serait pas préférée? Cependant, je peux définitivement voir qu'ils aideraient lors de la génération des itérateurs.

namespace Probability 
{ 
     /* ExpectedValueDataSet - Calculates the expected value of a data set */ 
     template <typename T, std::size_t N> 
     double ExpectedValueDataSet(const std::array<T, N>& data) 
     { 
      auto i = 0; 
      auto avg = 0; 

      for(auto it = data.begin(); it != data.end(); it++) 
      { 
       i = it - data.begin() + 1; 
       avg = ((i-1)/i)*avg + (*it)/i; 
      } 

      std::cout << avg << " \n"; 
      return avg; 
     } 

}; 
+2

Écrivez 'avg = 0.0' à la place et changez' avg = ((i-1)/i) * avg + ... 'en' avg = ((i-1) * avg/i) + ... ' – davidhigh

+0

** auto ** est une classe de stockage - variables stockées dans la pile, valeur perdue lorsque la fonction retourne - vous avez également besoin d'un spécificateur de type, puisque avg obtenu par division ** auto float avg = 0; ** fonctionnera correctement. –

+1

@ArifBurhan Cela a changé en C++ 11. L'utilisation de 'auto i = 0;' est complètement valide aujourd'hui - bien qu'elle puisse causer de la confusion si elle est surutilisée. – Sjoerd

Répondre

9

Le 0 littéral est de type int. La variable auto avg = 0; a donc le type int.

Le littéral 0.0 (ou par exemple 3.14) a le type double, ce qui est ce que vous voulez.


En règle générale, utiliser auto pour une déclaration de variable où

  • le type est explicitement spécifié dans le initialiseur ou

  • le type est terriblement bavard, comme certains iterator type.

Mais ne l'utilisez pas sans raison. :)


Si par ex. des raisons esthétiques que vous souhaitez conserver i comme un entier, puis réécrire le calcul

((i-1)/i)*avg + (*it)/i 

à, par exemple

((i-1)*avg + *it)/i 

pour éviter l'arithmétique entière pure pour (i-1)/i.

+0

Une note: cela ne corrige pas seul le code d'exemple car '(i-1)/i' est toujours' 0' donc la moyenne récursive est évaluée incorrectement. – davidhigh

+0

Ah, ça a beaucoup de sens. Cependant, comment l'auto gère-t-elle la différenciation entre un flotteur et le double par exemple? Ou un uint, int, ou longtemps? – Izzo

+0

@davidhigh, c'est le cas pour i = 0, mais pas pour i> 0. – Izzo