C++ 重载函数和模版
In C++, two different functions can have the same name if their parameters are different; either because they have a different number of parameters, or because any of their parameters are of a different type.
在c++中,两个函数可以有不同的名字,如果它们传递的参数类型不同。因为在传递参数时可以自动识别这是哪一个。但有默认参数,可能要注意产生冲突,最好不要这么做。
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
int divv (int a,int b)
{
return a+b;
}
int divv(int a,int b,int c=2)
{
return a+b+c;
}
int main()
{
std::cout << divv(2,3) << endl;
std::cout << divv(10,5) << endl;
return 0;
}
这种情况下来“欺骗编译器”,可是它根本不会被骗,而是直接便已报错”is ambigous”,但如果你多加一个参量就没事了,所以,从这个角度来讲,这个还是不必担心的。
2.函数模版
C++ has the ability to define functions with generic types, known as function templates. Defining a function template follows the same syntax as a regular function, except that it is preceded by the template keyword and a series of template parameters enclosed in angle-brackets <>:
一个函数可以向其中传递不同的参量,而不用像上面建立相同名字不同参数来复合不同变量的函数,C++的这种能力被称为函数模版。
模版必须在函数上面声明,下面你就可以看到很多例子了。
template function-declaration模版的函数声明
The template parameters are a series of parameters separated by commas. These parameters can be generic template types by specifying either the class or typename keyword followed by an identifier. This identifier can then be used in the function declaration as if it was a regular type. For example, a generic sum function could be defined as:
template <class SomeType>
SomeType sum (SomeType a, SomeType b)
{
return a+b;
}
generic function 泛型函数
generic type 通用型
关于它的作用:
In the code above, declaring SomeType (a generic type within the template parameters enclosed in angle-brackets) allows SomeType to be used anywhere in the function definition, just as any other type; it can be used as the type for parameters, as return type, or to declare new variables of this type. In all cases, it represents a generic type that will be determined on the moment the template is instantiated.
被传递参数的那一刻,该类型才会被确定下来。
For example, the sum function template defined above can be called with:
x = sum<int>(10,20);
The function sum is just one of the possible instantiations of function template sum. In this case, by using int as template argument in the call, the compiler automatically instantiates a version of sum where each occurrence of SomeType is replaced by int , as if it was defined as:
int sum (int a, int b)
{
return a+b;
}
instantiation 例子
定义的名字可以任意
In this case, we have used T as the template parameter name, instead of SomeType. It makes no difference, and T is actually a quite common template parameter name for generic types.
自动转换
模版函数的返回值存在多种可能,如果你忽略掉了,可能会报错,所以你需要这么写:x = sum<int>(10,20);
至少在本人电脑上不这么写就会错。
注意,在模版中的参数,这个问题你一定要明确,我们在刚开始使用T时,这时T属于未知状态,但当我们向函数中传递参数时,T的类型就被确定下来了,如果T仅出现一次,这没话说,可以自动转换,但是,要注意的是,当函数中出现的模版参数达到两次及以上,则必须要说明是那一个,否则就会报错
T sum (T a,T b)
这种情况下必须要在函数调用时声明相关变量,这种操作是你应该明确的。
而如果T sum (T a,U b){return T a+b}
,不需要在函数调用时声明其返回类型,返回值以传递的第一个a类型为准,弄明白就很简单了。
1.0 == 1
,这个判断为真,但 1 == 1.2
这个就判断为假,所以,语句的判断并非单纯的保留,还是很智能的,这个你一定要明确,不用担心这样判断会出错,就是这个样子。
template <class T, class U>
bool are_equal (T a, U b)
{
return (a==b);
}
int main ()
{
if (are_equal(10,10.0))
cout << "x and y are equal\n";
else
cout << "x and y are not equal\n";
return 0;
}
x and y are equal
这种混搭风,显然不会有冲突的,这个是要明确的。
Non-type template arguments
无类型的模版参数
// template arguments
#include <iostream>
using namespace std;
template <class T, int N>
T fixed_multiply (T val)
{
return val * N;
}
int main() {
std::cout << fixed_multiply<int,2>(10) << '\n';
std::cout << fixed_multiply<int,3>(10) << '\n';
}
可以看出在函数定义中未使用模版参数N,但在函数调用时,有<int,3>
,这样就会直接声明了有关值,本来N作为类似类的来进行,但这样就会直接变成变量,这样就可以直接使用参数N了。
注意,别妄想将已被使用的T给赋值,显然这样会报错,声明是:no matching function for call to ‘fixed_multiply’,显然这是在调用时出现了错误,别自作聪明。
就是这样,这算是我们接触到的第一个算是C++的正式特性吧,在后面还会有很多,慢慢好好学习吧!