1

Récemment, j'ai discuté avec les étudiants des possibilités de restriction de types pour les modèles qui utilise références de renvoi. Je savais sur la comparaison des types par is_same avec static_assert ou enable_if, mais nous avons également parlé de modèle explicite instanciation.Références d'instanciation et d'envoi de modèles explicites

L'exemple suivant fonctionne pour moi avec GCC:

f.h:

template <typename T>    
void f(T&& param); // declaration 

f.cpp:

#include <iostream> 

template <typename T> 
void f(T&& param) { std::cout << param << std::endl; } 

// explicit instantiations: 
template void f<int>(int&&); 
template void f<int&>(int&); 

main.cpp:

#include "f.h"  

int main() { 
    f(1);    
// f('1'); // LINKER ERROR 

    int i = 2;   
    f(i);    
}      

Je ne suis pas un expert en instanciations de modèles explicites, donc je me demande simplement si une telle solution est compatible avec les normes portatives. (S'il vous plaît, ne me demandez pas de cas d'utilisation, je n'ai pas. Pour moi, il est une question purement académique.)

MISE À JOUR

Je suis aussi un peu confus au sujet du format de l'instanciation explicite (<int>(int&&) et <int&>(int&)), mais je suppose qu'elle est donnée par déduction de gabarit et peut-être par référence à des règles de réduction.

Répondre

1

Ceci est correct et il est portable/standard.

Ceci est appelé la spécialisation de modèle et vous pouvez en savoir plus sur ce sujet here

spécialisation modèle est en train d'écrire un gestionnaire spécifique pour un Invoke spécifique. Dans votre code, vous avez deux spécialisations. Le premier reçoit une référence rvalue (par exemple un littéral entier comme 5) et renvoie un int.

La seconde reçoit une référence lvalue (par exemple la variable b qui est de type int et a une valeur de 5) et renvoie une référence lvalue.

Dans le cas par défaut, vous essayez d'imprimer le paramètre à l'aide de std::stringstream.