C++STL_Day2

trivial,non-trivial 函数,POD类型
enable_if
unsigned char
static_cast && dynamic_cast

trivial,non-trivial 函数,POD类型

  1. trivil,即不重要的,在以下四类函数中区分。
  • 构造函数 ctor
  • 拷贝构造函数 copy
  • 拷贝赋值运算符(赋值函数) assignment
  • 析构函数 dtor

这四种函数只要被显示声明(定义的话当然更是了),则为non-trivial类型。

class A { A();   };	//声明
class B { B(){}  }; //定义
class C {        };

int main() {
	//构造函数是否为trivial类型
	cout << is_trivially_constructible<A>::value << endl;//0
	cout << is_trivially_constructible<B>::value << endl;//0
	cout << is_trivially_constructible<C>::value << endl;//1

}
  1. Plain old data structure,即POD,为C++定义的一类数据结构,其经过二进制拷贝后数据仍保持不变的类型。POD类型包括标量类型POD类类型cv-限定类型,还有以其为基类的数组类型。
  • 标量类型(Scalar type):相对于复合类型,标量类型只能有一个值。C++语言中,int,char,enum,double,loob等均可归类为标量类型。
  • POD类类型:可以从两方面来归类该类型。(1) 构造函数,拷贝/移动构造函数,拷贝/移动赋值运算符,析构函数均为平凡的(non-trivial)且不包含虚函数,虚基类的类型即为POD类型。 (2) POD类类型是不具有以下成员的类型:指针到成员类型的非静态数据成员,非POD类类型的非静态数据成员,应用类型的非静态数据成员,用户定义的拷贝,赋值,析构操作。

class A { A();   };	//声明
class B { B(){}  }; //定义
class C {        };

class D { ~D();  };			//声明析构函数
int i= 1;
class E { static int i; };	//声明静态变量

int main() {
	//类类型是否为trivial类型
	cout << is_trivial<A>::value << endl;//0
	cout << is_trivial<B>::value << endl;//0
	cout << is_trivial<C>::value << endl;//1
	//类类型是否为POD
	cout << is_pod<A>::value << endl;	 //0
	cout << is_pod<B>::value << endl;	 //0
	cout << is_pod<C>::value << endl;	 //1
	//我们可以看到这俩函数其实差不多
	cout << "--------------------" << endl;
	cout << is_pod<D>::value << endl;	 //0
	cout << is_pod<E>::value << endl;	 //1 

	//其他就不测了......
}

参见

  1. https://www.cnblogs.com/zzyoucan/p/3918614.html
  2. https://baike.baidu.com/item/pod/13976181?fr=aladdin

enable_if

最近摸鱼又摸到这么宝贝。

  template <class Other1 = Ty1, class Other2 = Ty2,
    typename = typename std::enable_if<
    std::is_default_constructible<Other1>::value &&
    std::is_default_constructible<Other2>::value, void>::type>
    constexpr pair()
    : first(), second(){}

先不谈这个typename = 到底是在搞哪样。就这个enable_if,我还没搞懂到底有什么用,先设个坑吧。给出的链接讲的很详细,就是例子里的东西看不懂。
在这里插入图片描述
参见

  1. https://www.jianshu.com/p/a961c35910d2

unsigned char

  1. char 与unsigned char均为一个字节,唯一的区别就是char类型最高位为符号位,表示范围为[-128,127];unsigned char表示范围[0,255]。

  2. int/unsigned int变量赋值给 unsigned char变量是会发生字节截断(9位和高于9位的将被程序自动丢弃)。

		unsigned int a = 0xFFFFFFF7;
		unsigned char b = (unsigned char)a;
		printf("%x", b);//f7
  1. 在表示byte时,都用unsigned char。通常情况下,byte没有符号位,而将byte赋值给unsigned char之外的任何类型,都有可能发生符号扩展现象(包括unsigned char)。
    参见
  2. https://baike.baidu.com/item/unsigned%20char/3426526?fr=aladdin

static_cast &&dynamic_cast

static_cast其实就是c语言的强制类型转换…

	char a = 'c';
	int b = static_cast<char>(a);
	cout << b << endl;//99

	double*c = new double;
	void *d = static_cast<void*>(c);
	cout << typeid(d).name() << endl;//void*

	 int e = 10;
	 const int f = static_cast<const int>(e);

	 const int g = 10;
	 //错误,static_cast不能丢掉表达式的cv属性
	 int *h = static_cast<int*>(&g);
	 //正确,这条其实可以隐式转换。
	 int i = static_cast<int>(g);

dynamic_cast将基类对象指针或引用转换到继承类指针,static_cast同样可以执行此操作。需要注意的是static_cast,没有运行时检查来保证转换的安全性,dynamic_cast具有类型检查功能,这在基类向派生类转换时需要尤其容易出错。

参见

  1. https://blog.csdn.net/u014624623/article/details/79837849

最后我们来看一个例子。

	template<class Size>
	char *fill_n(char *first, Size n, const char&value) {
		memset(first, static_cast<unsigned char>(value), n);
		return first + n;
	}

<algorithm>中的fill函数的一个重载,用value填充first指向的内存,n是填充的字节数。
…其他也没什么好解释的了。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值