L'inférence de type de modèle C ++ est divisée en inférence de type de modèle de classe et d'inférence de type de modèle de fonction. La discussion principale ici est l'inférence de modèle de fonction C ++.
Il existe trois types de situations d'inférence de type de modèle de fonction:
Situation 1:
template<typename T>
void func(T t)
{
//....
}
Cette situation est la plus simple. Pour le paramètre réel val transmis au modèle de fonction, supposons que son type soit ParaType. Si ParaType a un attribut de référence, supprimez l'attribut de référence. S'il possède un attribut const, supprimez l'attribut de référence. Le type final est le type de T:
int i = 999;
func(i); //实参i既无引用属性,也无const属性,T类型为int
const int ci = 250;
func(ci); //实参ci有const属性,去掉,T类型为int
const int &cref = 520;
func(cref); //去掉实参cref引用属性和const属性,T类型为int
Situation 2:
template<typename T>
void func(T &t)
{
//...
}
Dans ce cas, pour le paramètre réel val transmis au modèle de fonction, le type est ParaType. Si ParaType a un attribut de référence, l'attribut de référence est supprimé et s'il a un attribut const, il est conservé.
int i = 999;
func(i); //实参i既无引用属性,也无const属性,T类型为int
const int ci = 250;
func(ci); //实参ci有const属性,T类型为const int
const int &cref = 520;
func(cref); //去掉实参cref引用属性,T类型为const int
const int &&crref = 6666;
func(crref); //去掉实参crref引用属性,T类型为const int
Situation 3:
template<typename T>
void func(T &&t)
{
//...
}
Cette situation est ce qu'on appelle la référence universelle. Le type de paramètre réel peut être n'importe quel type (lvalue, rvalue, lvalue reference, rvalue reference, bien que la fonction modèle const T&
puisse être déclarée pour recevoir n'importe quel type, mais le paramètre réel ne peut pas être modifié. limites).
Pour les paramètres réels passés à ce modèle de fonction:
- Lorsque le type d'argument est lvalue ** (notez que lvalue, lvalue reference et rvalue reference sont toutes des lvalues) **, le type de T sera déduit
type&
; lorsque le type de l'argument est une rvalue, le type de T Serait déduit de l'êtretype
. Detype
quel type s'agit-il?type
Autrement dit, la règle de dérivation dans le deuxième cas ci-dessus.
Par exemple:
std::string s("fuck");
func(s); //s为左值,type为std::stirng , T被推断为std::string &
const std::string &lref = s;
func(lref); //lref为左值,type为const std::string T被推导为const std::string &
const std::string &&rref = std::string("fuck c++");
func(rref); //同上
- Lorsque le type de paramètre réel est une rvalue, le type de T est déduit comme étant le type correspondant du paramètre réel.
Par exemple:
func(std::string("hello c++"); //T被推断为std::string
std::string s("give up c++");
func(std::move(s)); //T被推断为std::string
func(static_cast<std::string &&>(s)); //T被推断为 std::string
Jusqu'à présent, tous les types de T sont connus. Vous pouvez directement importer le type inféré dans le modèle de fonction pour obtenir la fonction instanciée, par exemple:
//情况一
func(int t) //T为int
{
//...
}
//情况二
func(const int &t) //T为const int
{
//...
}
//情况三,实参为左值时
func(const std::string& &&t) //T为const std::string &
{
//...
}
//情况三,实参为右值时
func(std::string &&t) /T为std::string
{
//...
}
Dans le troisième cas, le résultat de l'instanciation est un peu étrange lorsque le paramètre réel est une valeur l. Le compilateur ne permet pas au programmeur d'écrire ceci directement, en le repliant par référence, la version finale est:
//可以看到,当实参为左值类型(左值、左值引用、右值引用)时,最终t都会绑定到一个左值对象或右值对象上
func(const std::string &t)
{
//....
}