C++ function template parameter inference

C++ template type inference is divided into class template type inference and function template type inference. The main discussion here is C++ function template inference.

There are three types of function template type inference situations:

Situation 1:
template<typename T>
void func(T t)
{
	//....
}

This situation is the simplest. For the actual parameter val passed to the function template, suppose its type is ParaType. If ParaType has a reference attribute, then remove the reference attribute. If it has a const attribute, remove the reference attribute. The final type is the type of 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)
{
	//...
}

In this case, for the actual parameter val passed to the function template, the type is ParaType. If ParaType has a reference attribute, the reference attribute is removed, and if it has a const attribute, it is retained.

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)
{
	//...
}

This situation is the so-called universal reference. The actual parameter type can be any type (lvalue, rvalue, lvalue reference, rvalue reference, although the template function const T&can be declared to receive any type, but the actual parameter cannot be modified. limits).

For the actual parameters passed to this function template:

  1. When the argument type is lvalue** (note that lvalue, lvalue reference, and rvalue reference are all lvalues) **, the type of T will be inferred type&; when the type of the argument is an rvalue, the type of T Would be inferred to be type. That typewhat type is it? typeThat is, the derivation rule in the second case above.
For example:
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);		//同上
  1. When the actual parameter type is an rvalue, the type of T is inferred to be the corresponding type of the actual parameter.
For example:
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

So far, all the types of T are known. You can directly bring the inferred type into the function template to get the instantiated function, for example:

//情况一
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
{
	//...
}

In case three, the instantiation result is a bit strange when the actual parameter is an lvalue. The compiler does not allow the programmer to write this directly, folding by reference, the final version is:

//可以看到,当实参为左值类型(左值、左值引用、右值引用)时,最终t都会绑定到一个左值对象或右值对象上
func(const std::string &t)	
{
	//....
}

Guess you like

Origin blog.csdn.net/qq_39815320/article/details/104971118