- 语法细节
- 类内的静态(static)成员在类外定义的时候不加static
- typename的作用
- 1. 一种是在声明模板类、模板函数的参数的时候
- 2. 还有一种是在取别名的时候
- std::enable_if 的几种用法
- 定义
- cin cout endl都是什么
- endl 是一个函数 参数是basic_ostream
- cin cout 是两个对象
- 【在指定的地址构造对象】placement new
- 【STL内存拷贝】std::memmove
想法来源
为了巩固C++知识,在知乎上调研了一番之后
决定采用陈硕前辈的想法
计划自己实现一个简易版本的vector
再实现一个string类
然后将string 放进vector里面
知乎
如何从零开始手写一个tiny STL? - 陈硕的回答 - 知乎
https://www.zhihu.com/question/53085291/answer/133458242
语法细节
类内的静态(static)成员在类外定义的时候不加static
包括静态成员函数,在类外实现的时候不需要再加上static了
否则会报错
每一个cpp文件最后都编程了一个翻译单元
对于静态变量
因为在cpp的翻译单元总,静态变量只在一个单元内部可见
但是类内的static却要在其他的cpp中也可以使用,这样在类外定义这个变量的时候
就不能在外面继续加上static了 否在就没法和cpp文件里面的static变量区分了
对于静态函数
也是如此
加上static之后,一个cpp中定义了函数,在其他的cpp中就访问不到了
可能的原因
typename的作用
typename有两种用发,
1. 一种是在声明模板类、模板函数的参数的时候
2. 还有一种是在取别名的时候
Eg1:
template<typename T>
class vector {}
Eg2:
using value_type = typename allocator<T>::value_type;
告诉编译器 allocator<T>::value_type 是一个类型名称
使用 typename 的作用就是告诉 c++ 编译器,typename 后面的字符串为一个类型名称,而不是成员函数或者成员变量,这个时候如果前面没有 typename,编译器没有任何办法知道 T::LengthType 是一个类型还是一个成员名称(静态数据成员或者静态函数),所以编译不能够通过。
std::enable_if 的几种用法
定义
template <bool, typename T=void>
struct enable_if {
};
template <typename T>
struct enable_if<true, T> {
using type = T;
};
由上可知,只有当第一个模板参数为 true 时,type 才有定义,否则使用 type 会产生编译错误,并且默认模板参数可以让你不必指定类型。下面说说它的几种使用方法
cin cout endl都是什么
endl 是一个函数 参数是basic_ostream
源码
// MANIPULATORS
template <class _Elem, class _Traits>
basic_ostream<_Elem, _Traits>& __CLRCALL_OR_CDECL endl(
basic_ostream<_Elem, _Traits>& _Ostr) { // insert newline and flush stream
_Ostr.put(_Ostr.widen('\n'));
_Ostr.flush();
return _Ostr;
}
向_Ostr中加了一个\n
之后刷新了流
cin cout 是两个对象
__PURE_APPDOMAIN_GLOBAL extern istream cin;
__PURE_APPDOMAIN_GLOBAL extern ostream cout;
分别重载了>> <<
【在指定的地址构造对象】placement new
#include <iostream>
using namespace std;
int main()
{
int a = 10;
int* p = &a;
::new ((void*)p) int(2);
std::cout << a << std::endl;
return 0;
}
【STL内存拷贝】std::memmove
#include <iostream>
#include <cstring>
int main()
{
char str[] = "1234567890";
std::cout << str << '\n';
std::memmove(str + 4, str, 3); // copies from [4, 5, 6] to [5, 6, 7]
std::cout << str << '\n';
}