Je pense que vous pourriez être confus entre rvalues et le qualificateur de const. function
renvoie un rvalue non-const temporaire de type int, de sorte que le compilateur déduit T comme étant int, comme il le devrait. Comme vous le faites remarquer, vous pouvez lier un temporaire à un const ref (C++ 03 12.2/5), mais le compilateur n'ajoutera pas de qualificatifs cv pour rendre un appel de fonction bien formé. Puisque vous ne pouvez pas contrôler la fonction de modèle, il existe deux façons de contourner cela (en plus de la solution que vous avez publiée).
(1) paramètres du modèle explicite: function2<const int>(function())
(2) cv retour se qualifier: const int function();
Ces deux solutions sont bien formées. (1) semble la meilleure solution, à mon humble avis, puisque (2) est non conventionnel et stupide. Edit: En fait, le type déduit peut être plus qualifié en cv que l'argument pour un argument de modèle ref, mais seulement si la déduction de type échoue autrement (C++ 03 14.8.2.1/3). Dans ce cas, la déduction de type n'échoue pas, mais aboutit à un appel de fonction mal formé (SFINAE ne s'applique pas, car la spécialisation de la fonction de template elle-même n'est pas malformée). Si l'intention de l'auteur du modèle était de ne pas modifier l'argument, il doit être déclaré comme argument de référence const, donc cela peut être un bogue dans la bibliothèque de templates, ou il peut modifier l'argument, auquel cas vous allez échouer là où la fonction tente de modifier l'argument. Editer: Comme le souligne FredOverflow, les valeurs hors classe sont toujours non qualifiées par le standard 3.10/9. Donc (2), qui fonctionne sous gcc 4.3, est en fait un bogue du compilateur (gcc < 4.5, d'après FredOverflow).
@aca Pour être plus précis, [les valeurs hors classe ont toujours des types cv-non qualifiés] (http: // stackoverflow.com/questions/2169932/non-class-rvalues-toujours-have-cv-unqualified-types) ;-) Pour les types-classes, il y a une distinction entre rvalues modifiables et const rvalues, donc en général, le 'const' est * pas * superflu! Vous pouvez appeler des méthodes non-const sur des valeurs modifiables et ainsi modifier les objets sous-jacents. Par exemple, 'std :: string (" bonjour ") .append (" monde! ")'. – fredoverflow
@FredOverflow yep bon point. Notez que les valeurs de tableau sont qualifiées de la même manière (la norme dit qu'elles ne le sont pas, mais elles ne le sont pas - vous ne pouvez écrire 'struct A {const int a [1];}; .. A(). A [0] = 0;' dans la plupart des compilateurs (sauf dans comeau, où vous pouvez) - mais si vous supprimez le 'const', vous pouvez (il y a eu des questions sur usenet et ailleurs à ce sujet - aucune solution n'a encore été trouvée). class/non-array rvalue n'est pas un objet Les rvalues type-classe/type tableau sont des objets, donc const a du sens pour eux (voir foot-note sur 4.1/1 dans la norme) –
@FredOverflow je me demande ce que @aca Est-ce qu'il a retiré son commentaire? –