static_cast <new type>(expression)
常用场合
可以用于低风险的转换:
- 整形和浮点型
- 字符和整形
- 转换运算符
- 空指针转换成任何目标类型的指针
不可用于较高风险的转换
- 不同类型的指针之间的相互转换
- 整形和指针之间的相互转化
- 不同类型的引用之间的转换
1、编译器隐式执行的任何类型的转换都可以由static_cast 完成,不会产生warning
double a = 1.999;
int b = static_cast<int> (a);
使用static_cast可以明确告诉编译器,这种损失精度的转换是在知情的情况下进行的,也可以让阅读程序的其它程序员明确你是有意识的转换而不是由于疏忽。
2、使用static_cast可以找回存放在void*指针中的值
double a = 1.999;
void * vptr = & a;
auto * dptr = (double*)(vptr);
cout<< (*dptr)<<endl;//输出1.999
3、static_cast用于基类与派生类的转换过程中,但是没有运行时类型检查
注意从下向上(子类到基类)的转换是安全的,从上向下(基类到子类)的转换不一定安全。
Templates (C++)
模板函数
template <typename T>
T minimum(const T& lhs, const T& rhs)
{
return lhs < rhs ? lhs : rhs;
}
调用的时候,可以显示声明类型,编译器也可以自动推断类型,想普通函数一样去调用它
int a = get_a();
int b = get_b();
int i = minimum<int>(a, b);
// 直接调用
int i = minimum(a, b);
当执行 minimum(a,b) 时,会叫模板中所有的T替换成 int
int minimum(const int& lhs, const int& rhs)
{
return lhs < rhs ? lhs : rhs;
}
模板类
template <typename T, typename U, typename V> class Foo{};
typename 和 class 等同
template <class T, class U, class V> class Foo{};
可变长参数
template<typename... Arguments> class vtclass;
vtclass< > vtinstance1;
vtclass<int> vtinstance2;
vtclass<float, bool> vtinstance3;
非类型参数 Non-type parameters
非类型参数,也称为值参数。用来传值
template<typename T, size_t L>
class MyArray
{
T arr[L];
public:
MyArray() { ... }
};
MyArray<MyClass*, 10> arr;
size_t 变量的值,在编译时时常量或者常指针。
非类型参数能自动推断类型
使用 auto 关键字
template <auto x> constexpr auto constant = x;
auto v1 = constant<5>; // v1 == 5, decltype(v1) is int
auto v2 = constant<true>; // v2 == true, decltype(v2) is bool
auto v3 = constant<'a'>; // v3 == 'a', decltype(v3) is char
Templates as template parameters 模板作为模板参数
个人感觉翻译为模板嵌套好理解?
template<typename T, template<typename, int> class Arr>
class MyClass2
{
T t; //OK
Arr<T, 10> a;
};
模板缺省值
template <class T, class Allocator = allocator<T>> class vector;
vector<int> myInts;
vector<int, MyAllocator> ints;
全部缺省
template<typename A = int, typename B = double>
class Bar
{
//...
};
...
int main()
{
Bar<> bar; // use all default type arguments
}
Template specialization
我翻译为模板定制化???
简而言之,就是通过模板参数类型,选择同名类的不同实现
template <typename K, typename V>
class MyMap{/*...*/};
// partial specialization for string keys
template<typename V>
class MyMap<string, V> {/*...*/};
...
MyMap<int, MyClass> classes; // uses original template
MyMap<string, MyClass> classes2; // uses the partial specialization