> In file included from /usr/include/c++/4.8/bits/char_traits.h:39:0, > from /usr/include/c++/4.8/ios:40, > from /usr/include/c++/4.8/ostream:38, > from /usr/include/c++/4.8/iostream:39, > from sum_to.cpp:1: /usr/include/c++/4.8/bits/stl_algobase.h:239:5: note: template<class > _Tp, class _Compare> const _Tp& std::min(const _Tp&, const _Tp&, _Compare) > min(const _Tp& __a, const _Tp& __b, _Compare __comp) > ^ /usr/include/c++/4.8/bits/stl_algobase.h:239:5: note: template argument deduction/substitution failed: sum_to.cpp:7:29: > note: deduced conflicting types for parameter âconst _Tpâ (âintâ and > âlong long intâ) > std::cout<<std::min(a, b); ---
5 Réponses :
car intégré << / code> s'applique Promotions numériques < / a> et la déduction de l'argument de modèle ne fait pas. p>
Pourriez-vous s'il vous plaît donner une référence spécifique à << / code>? J'ai compris promotions code> mais je ne peux pas savoir pourquoi << / code> convient à ce Promotions code>.
@Kamel C'est le cas pour tous les opérateurs arithmétiques intégrés ( lien ).
J'ai lu le document de Java pour apprendre à utiliser son SDK, tout en lisant le document C ++ pour apprendre comment son compilateur ticks à exécuter le code.
@Kamel si vous voulez dire que c ++ est inégalé, ce n'est pas. C'est juste beaucoup plus complexe que Java, et vous devez en savoir plus de ses morceaux pour voir qu'ils correspondaient bien ensemble.
L'héritage de C. Appelez cela la malédiction de la compatibilité à l'envers avec le code remontant 3 décennies.
C'est parce que std :: min code> est une fonction de modèle.
template <class T> const T& min (const T& a, const T& b) {
return !(b<a)?a:b; // or: return !comp(b,a)?a:b; for version (2)
}
Les types primitifs ne surchargent pas les opérateurs de surcharge, les les conversions arithmétiques habituelles em> sont appliquées et votre INT est converti en une longue longue et le "<" a une signification valide. Vous ne pouvez même pas surcharger des opérateurs pour des types primitifs:
https://isocpp.org/wiki/faq/intrinsic-types # Intrinsics-and-Opérateur-Overloading P> Exemple Pour montrer que votre INT est favorisé à long long p> documentation
http://en.cppreference.com/w/cpp/language/operator_arithmetic P> pour les opérateurs binaires (sauf quarts de travail), si les opérandes promus
avoir des types différents, un ensemble supplémentaire de conversions implicites est
appliqué, connu sous le nom de conversions arithmétiques habituelles avec le but de
produire le type commun (également accessible via le type STD :: Common_Type
TRAIT) P>
blockQuote> p>
Chaque paire de types d'arithmétiques promus a des opérateurs définis pour cette paire. int code> est déjà un type arithmétique favorisé. La promotion ne produit rien avec un rang supérieur à int code> sauf s'il ne change pas le type. int code> -> long long code> n'est pas une promotion valide.
S'il vous plaît vérifier ma réponse mise à jour, je crains que votre commentaire ne reflète pas ce qui se passe en réalité. «Promuté» peut ne pas avoir été le bon terme, mais des "conversions arithmétiques habituelles" sont appliquées.
L'opérateur sinon << / code> est binaire, le compilateur pourrait donc convertir des arguments vers le même type et les comparer. P>
min code> doit renvoyer quelque chose. Comment le compilateur pourrait-il deviner quel type devrait-il revenir? P>
Comme expliqué dans d'autres réponses, la raison est que pour chaque paire de types arithmétiques promus std :: min code> nécessite que les types d'arguments soient identiques si la déduction doit être effectuée, tandis que implique Les conversions arithmétiques habituelles (§5.9 / 2), qui veilleront à ce que les types soient convertis en un "dénominateur commun". Notez comment §13.6 / 12 énumère les opérateurs intégrés en tant que candidats:
l code> et r code>, il existe
Fonctions de l'opérateur candidat de la forme p>
template <typename T>
constexpr decltype(auto) min(T&& t) {return std::forward<T>(t);}
template <typename T, typename U, typename... Args>
constexpr auto min(T&& t, U&&u, Args&&... args) {
std::common_type_t<T, U> const& _t(std::forward<T>(t)), _u(std::forward<U>(u));
return min(_t<_u? _t : _u, std::forward<Args>(args)...);
}
N'est pas t susceptible de convertir t code> et u code> sur common_type_t
@Yakk j'ai essayé autre chose. Cependant, il pourrait y avoir un opérateur << / code> qui compare des types de classe distincts. Ensuite, a effectue seulement deux copies à Common_Type Code>, tandis que le mien effectue trois en tout cas. Je ne suis pas si dérangé par les types primitifs, car je pense que les compilateurs optimisent en conséquence pour ceux-ci.
Si nous n'appliquons pas l'ordre de << / code> (raisonnable), et notre min code> renvoie une référence (dans la mesure du possible), alors min (A, B, c. ..) code> étant auto && x = min (avant (b), avant (c) ...); Retour no_rvalue (A no_rvalue code> convertit les avales en valeurs et laisse seules les livres? Je suppose que si b code> est un rvalue et c ... code> est vide, cela provoque une copie supplémentaire. gah. Besoin de distinguer entre les vrais temporaires (locaux) et les temporaires passés? Pour éviter des copies supplémentaires.
Parce que fait i> conversions en compte.