完成了奇牛编程中万能择优器项目,总结了一些知识盲点。
size_type
在C++中,size_type
是在标准库容器类(如 std::vector
, std::string
, std::list
等)中定义的一个类型别名,通常用于表示容器中元素的数量或容器的大小。它是一个无符号整数类型,确保可以存储足够大的正整数值。每个容器类都有自己的 size_type
,它们的定义通常如下:
typedef implementation-defined size_type;
举个例子,如果你有一个 std::vector<int>
,你可以使用它的 size_type
来声明变量,例如:
std::vector<int> vec = {1, 2, 3, 4, 5};
std::vector<int>::size_type vecSize = vec.size();
在这个例子中,vecSize
的类型是 std::vector<int>::size_type
,它被定义为一个无符号整数类型,能够表示 vec
的大小.
当然,你可以使用int
类型来接收,但是使用 size_type
有几个好处:
- 提高移植性:不同平台上整数类型的大小可能不同,使用容器定义的
size_type
可以确保代码在不同平台上的一致性 - 避免警告:如果使用带符号整数来表示大小,可能会产生不必要的编译器警告或错误。使用
size_type
可以避免这些问题,因为它是一个无符号类型 - 提高代码的易读性:代码更清晰,因为使用
size_type
明确表示该变量是用来存储大小或计数的
value_type
value_type
通常用于表示容器中存储的元素类型。与 size_type
类似,value_type
是在标准库容器类(如 std::vector
, std::list
, std::map
等)中定义的一个类型别名。其定义如下:
typedef implementation-defined value_type;
如果你有一个 std::vector<int>
,它的 value_type
就是 int
。你可以使用它的 value_type
来声明变量或迭代器,例如:
std::vector<int> vec = {1, 2, 3, 4, 5};
std::vector<int>::value_type val = vec[0]; // val 的类型是 int
它的优点与 size_type
相同.
项目实战
在奇牛编程万能择优器中,可以如下书写,提高代码的规范性和易读性
#ifndef __SIZEFILTER__
#define __SIZEFILTER__
#include <iostream>
#include <set>
using namespace std;
template<typename _Ty, typename _Container = set<_Ty>>
class sizeFilter {
public:
typedef sizeFilter<_Ty, _Container> _Myt; // 必须定义在类的内部
typedef typename _Container::size_type size_type; // 需要使用 type_name 进行修饰
typedef typename _Container::value_type value_type;
···
private:
_Container c;
}
#endif
同时,在项目中有以下几点总结:
-
模板类中使用的依赖于模板参数的类型需要用
typename
关键字进行修饰。这是因为在模板定义中,编译器在解析模板时并不知道_Container::size_type
是否是一个类型名(type name)还是一个数据成员名(value name)。 -
模板类的别名必须定义在类模板内部。这样做是因为模板参数在类外部不可见,而在类内部定义的别名可以访问这些模板参数。如果你尝试在类模板外部定义别名,编译器将无法解析模板参数,从而导致编译错误。
-
在c++中,类的别名必须通过
typedef
或者using MyAlias = MyClass;
(其中MyClass
为类的名称,MyAlias
是别名)来定义,不存在类似结构体定义别名的方法:typedef struct MyStruct { int a; float b; } MyStructAlias;
-
在
set
或multiset
中,一般情况下,set
在使用insert
插入元素后,将返回一个pair<set<type>::iterator, bool>
,因为其不允许插入相同元素,插入可能失败;multiset
则默认返回一个迭代器,因为它当中的元素可以相同,其不需要bool
类型判断是否插入成功。我们可以在
insert
后加入迭代器指定插入位置,此时,无论是set
还是multiset
都将返回一个迭代器,指向插入的新元素的位置。但是即使在insert
函数中指定了插入位置,插入的元素仍会按顺序排列,而不会直接插入到指定的位置。其设计的目的是为了优化插入操作的效率。虽然set
或multiset
总是保持有序,但通过提供一个提示(hint),你可以帮助set
更快地找到正确的插入位置,从而提高性能。具体来说,提示(hint)是一个迭代器,表示你认为新元素应该插入的位置。
set
或multiset
会从这个位置开始搜索正确的插入点,而不是从头开始搜索。但是如果位置错误,将会按照正常插入流程重新插入。