存档

文章标签 ‘c++’

《C++ 模板》翻译: 1.2 模板参数推导

2020/05/25 16

当我们使用参数调用 max() 这样的模板时,模板参数就由我们传递的参数确定下来。如果我们给参数类型 T 传两个 int ,C++ 编译器就会推断出 T 一定是 int 。但是, T 可能只是这个类型的 “一部分” 。例如,我们声明 max() 的参数为常量引用:

然后传递 int 类型参数, T 还是会被推导成 int ,因为函数参数 int const& 相匹配。

类型推导中的类型转换
注意, 在类型推导过程中,禁止了类型自动转换:

  • 当声明为引用类型参数时,任何一丢丢的类型转换都不适用于类型推导。使用相同模板参数 T 声明的两个参数必须完全匹配
  • 当声明为值类型参数时,只支持 退化(decay) 这一种普通的转换。const 或 volatile 限定符会被忽略,引用转换为被引用的类型,原始数组和函数会被退化为相应类型的指针。两个使用相同的模板参数 T 的 退化 也必须相同。

阅读全文…

《C++ 模板》翻译: 1.1 初识函数模板

2020/05/24 37

本章介绍函数模板。 函数模板是参数化的函数,它们表示一系列函数

1.1 初始函数模板

函数模板的的的提供了可为不同的类型调用函数行为,换名话说,函数模板表示一系列函数。这表示它看起来像个普通函数,除了某些元素是不确定的:这些元素是参数化(parameterized)的。为说明这点,我们来看些例子

1.1.1 定义模板

下面是一个函数模板,经返回两个值中的最大值:

这个模板定义了一系列函数,它们返回两个值中的最大值,这两个值通过函数的参数 a 和 b1 传递。这些参数的类型为 template parameter T [?.1] . 正如上例所示,模板参数需要使用如下语法声明:

在本例中,参数列表为 typename T . 注意这里尖括号 < > 是如何使用的, 而关键词 typename 引入了 类型参数(type parameter)。 目前为止,这是 C++编程中最常见的一种模板参数,但也可以使用其它参数,这点我们稍后讨论(参见第 3 章)

阅读全文…

《C++ 模板》翻译: 第一部分 基础

2020/05/24 16

此部分介绍 C++ 模板的一般概念与语言特性。我们首先通过展示函数模板和类模板的例子来讨论一般的目标和概念,然后是是附属的基础模板特性, 如 非类型模板参数(nontype template parameters)、可变参数模板(variadic templates,)、typename 关键字 和 成员模板。我们也会讨论如何处理 移动语义(move semantics), 如何定义参数, 以及如何在 编译时编程(compile-time programming) 使用泛型代码 。最后给出了一些关于术语的一般性提示,以及作为应用程序的程序员和泛型库作者在实践中使用和应用模板的提示。

阅读全文…

C++ 构造函数漫谈(四)

2019/08/21 259

这一章谈 C++11 中引入的两种 “语法糖” .使用它们可以使得我们的代码更为简洁优雅。

委托构造函数

在同一个类中,一个构造函数可以调用另一个构造函数,这叫委托构造函数。这是 C++ 11 的新特性。
委托构造函数可以简化在每个构造函数中的重复代码。

注意一点,委托构造函数在使用时不可以形成环:禁止套娃。

阅读全文…

C++ 构造函数漫谈(三)

2019/08/19 269

这一章聊一聊在面向对象的C++中,构造函数的调用顺序。

数据成员的构造顺序

一个类的数据成员的初始化顺序只与其在类中的声明顺序相关,与其它无关。

而析构时,如果成员是在堆中,析构顺序正好与构造时相反。

类A的成员的构造顺序为: m1_, m2_, pm1_, pm2_ 。析构时的顺序为 m2_, m1_ ,由于 pm1_, pm2_ 不在堆中,所以它们的析构需要类A自己管理。

阅读全文…

C++ 构造函数漫谈(二)

2019/08/18 380

三五零法则

我们知道,编译器会为类自动生成几个特别的成员函数:构造函数、复制构造函数、复制赋值运算符、析构函数。后三者比较特殊,我们在下面会频繁提到。

三法则

若一个类需要用户显式定义 析构函数、复制构造函数、复制赋值运算符 中的一个,那么这三个函数都需要显式定义 。如果用户显式定义了其中一个,另外两个还是会被编译器隐式定义,这种混杂的情况容易生产无法预期的错误。
如果一个类中有非基本数据类型或者非类类型的成员(如指针、文件描述符等),则这一法则表现的更为明显:隐式析构函数无法对这种成员进行有效的释放,隐式复制构造函数和隐式复制赋值运算符无法进行深拷贝。

阅读全文…