模板:函数模板

1 模板的基础知识

1.1 模板的参数

Template Parameter vs Template Arguments
在技术文献中:parameter翻译成形参(format parameter), argument翻译成实参(actual parameter).

A type parameter can be used to name the return type or a function parameter type, and for variable declarations or casts inside the function body. Each type parameter must be preceed by the keyword typename .

点击查看代码
template <typename T> T foo(T* p) {
    T tmp = *p;
    // ...
    return tmp;
}

// error: must precede U with either typename or class
template <typename T, U> T calc(const T&, const U&);

模板除了可以有类型参数(type parameter),还可以有非类型参数(non-type parameter).

A template nontype parameter is a constant value inside the tempalte definition. A nontype parameter can be used when constant expressions are required, for example, to specify the size fo an array.

点击查看代码
template < unsigned N, unsigned M>
int compare(const char (&p1)[N], const char (&p2)[M]) {
    return strcmp(p1, p2);
}
// 如果调用函数如下
compare("hi", "mom");
// 该模板函数会被实例化下面这个函数
int compare(const char (&p1)[3], const char (&p2)[4]) { ... }

1.2 模板的分类

  • function template 函数模板 (recipes for making functions)
  • class templates 类模板 (recipes for making classes)
  • member function templates 成员函数模板(recipes for making member functions of classes)
  • alias templates (C++ 11引入) 别名模板(recipes for making type aliases)
  • variable templates(C++ 14引入) 变量模板(recipes for making variables or static data members)
  • lambda templates (C++ 20引入)
    image

A template is not a thing —— it is a recipe for making things.

2 模板的特化(specialization)

The concrete entity resulting from substituting template arguments for template parameters is a specialization.

image

image

下面给几个函数模板特化(Expliciit Specialization)、Implicit Instantiation和Explicit Instantiation的例子。(类模板才有偏特化[Partial Specialization])

点击查看代码
template<typename T>
T const& min(T const&a, T const& b) {
	return (b < a) ? b : a;
}

// Explicit Specialization
template<>
int const& min(int const& a, int const& b) {
	return (b - 10 < a) ? b : a;
}

double d1 = 2.78;
double d2 = 3.14
// Implicit Instantiation
double d3 = min<double>(d1, d2);
// Implicit Instantiation
double d4 = min(d1, d1)
点击查看代码
#include <iostream>
#include <string>


template<typename T>
T MyMin(const T& a, const T& b) {
    return (a < b) ? a : b;
}

// Explicit Specialization
template<>
double MyMin(const double& a, const double& b) {
    return 0.112;
}

// Explicit Instantiation
template int MyMin(const int& a, const int& b);

int main() {
    int a = 3;
    int b = 4;
    float x = 1.2;
    float y = 1.1;
    double m = 1.200;
    double n = 2.100;
    std::cout << MyMin(a, b) << std::endl;
    std::cout << MyMin(x, y) << std::endl;
    std::cout << MyMin(m, n) << std::endl;

	// Implicit Instantiation
    std::string s1 = "hello";
    std::string s2 = "world";
    std::cout << MyMin(s1, s1) << std::endl;
    return 0;
}
相比Implicit Instantiation, Explicit Instantiation可以加快编译速度。 参考资料: [《cppreference: Function Template》](https://en.cppreference.com/w/cpp/language/function_template "《cppreference: Function Template》")

3 函数的默认参数

点击查看代码
#include <iostream>
#include <string>

// Function Declaration
int myadd(int a = 2, int b = 3);
int mysub(int a = 6, int b = 3);

// Function Definition

// OK
int myadd(int a, int b) {
    return a + b;
}

// Error
int mysub(int a = 6, int b = 3) {
    return a - b;
}

int main() {
    int x = 10;
    int y = 5;
    std::cout << myadd(x, y) << std::endl;
    std::cout << mysub(x, y) << std::endl;
    return 0;
}
posted @ 2022-09-29 23:19  渐渐的笔记本  阅读(47)  评论(0编辑  收藏  举报