栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

探究stl

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

探究stl

系列文章目录

提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加
例如:第一章 Python 机器学习入门之pandas的使用


提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录
  • 系列文章目录
  • 前言
  • 一、重写STL建议
  • 二、c++新特性keyword(言简意赅)
    • 1.explicit和implicit
    • 2.noexcept
  • 三、type_trait
  • 四、construction
  • 五、util
    • 1 move和forward
    • 2 pair


前言

帮助c++初学者更加友好的了解c++STL源码剖析


提示:以下是本篇文章正文内容,下面案例可供参考

一、重写STL建议

STL可分为容器(containers)、迭代器(iterators)、空间配置器(allocator)、配接器(adapters)、算法(algorithms)、仿函数(functors)六个部分。type_trait->construction->util

二、c++新特性keyword(言简意赅) 1.explicit和implicit

首先在了解keyword之前你得先了解隐式转换(implicit conversion)和显示转换(explicit conversion)

 int a=1;//编译器帮你做的转换-explicit
 float b =(float)a//强制转换-implicit

然后让我们来了解 keyword
explicit:在C++语言中,类中的构造函数如果只含有一个参数,默认情况下存在一种隐式转换,即定义了转换为此类类型的隐式转换机制。然而,这种机制并非总是合理的,甚至容易产生错误,因此,新标准增加了explicit关键字,用来限制隐式转换。

class Test {
public:
Test(); // 空构造函数
Test(double a); // 含一个参数的构造函数
Test(int a, int b); // 含两个参数的构造函数
Test(int a, double b = 1.2); // 带有默认初始值的构造函数
~Test();
};

// 调用
Test d1(12.3); // 直接调用含一个参数的构造函数
Test d2 = 1.2; // 也是调用含有一个参数的构造函数,但是包含一次隐式转换
Test d3(12, 13);
Test d3 = 12; // 隐式转换,调用带有默认初始值的构造函数Test(int a, double b = 1.2)

explicit可以阻止构造函数的隐式转换,但是只能对含有一个参数,或者有n个参数,但是其中 n-1 个参数是带有默认值的构造函数有效,其余的构造函数,explicit无法进行约束

class Test {
public:
    Test() {}  // 空构造函数
    explicit Test(double a); // 该构造函数无法进行隐式类类型转换
    explicit Test(int a, int b);  // 含有两个参数,explicit对其无效,然而该构造函数本身也是不能隐式转换的
    explicit Test(int a, double b = 1.2);  // 该构造函数无法进行隐式类类型转换
    ~Test() {}
};

// 调用
Test d1(12.3);  // 正确
Test d2 = 1.2;  // 错误,不能进行隐式类类型转换
Test d3(12, 13);  // 正确
Test d3 = 12;  // 错误,不能进行隐式类类型转换

https://blog.csdn.net/readyone/article/details/112371671
implicit:
与其相对应的implicit则代表着隐式的类构造函数,因为在默认的情况下,类构造函数都是隐式的,所以后者没有前者常用,也较少被提及。

2.noexcept

表示函数不会抛出异常的动态异常声明throw()也被新的noexcept异常声明所取代。
https://blog.csdn.net/LaoJiu_/article/details/50781352

三、type_trait

代码解析:

namespace mystl
{

// helper struct

template 
struct m_integral_constant
{
  static constexpr T value = v;
};

template 
using m_bool_constant = m_integral_constant;//c++ using 使用:取别名
//重命名
typedef m_bool_constant  m_true_type;//省略 一个模板参数 b 
typedef m_bool_constant m_false_type;


// type traits

// is_pair

// --- forward declaration begin
template 
struct pair;
// --- forward declaration end

template 
struct is_pair : mystl::m_false_type {};//继承

template 
struct is_pair> : mystl::m_true_type {};

} // namespace mystl
四、construction

代码如下:

namespace mystl
{

// construct 构造对象

template 
void construct(Ty* ptr)
{
  ::new ((void*)ptr) Ty();//全局参数
}

template 
void construct(Ty1* ptr, const Ty2& value)
{
  ::new ((void*)ptr) Ty1(value);//使用new 来 构造  一个copy construct :value
}

template //init 列表 :(1,3,5,6)作为参数
void construct(Ty* ptr, Args&&... args)
{
  ::new ((void*)ptr) Ty(mystl::forward(args)...);//完美保持右值属性 参考:
}

// destroy 将对象析构

template 
void destroy_one(Ty*, std::true_type) {}

template 
void destroy_one(Ty* pointer, std::false_type)
{
  if (pointer != nullptr)
  {
    pointer->~Ty();
  }
}

template 
void destroy_cat(ForwardIter , ForwardIter , std::true_type) {}//cat 有浏览的意思  一个一个来解析(Iter:Iterator)

template 
void destroy_cat(ForwardIter first, ForwardIter last, std::false_type)
{
  for (; first != last; ++first)
    destroy(&*first);
}

template 
void destroy(Ty* pointer)
{
// determine whether remove_all_extents_t<_Ty> is a reference type or can trivially be explicitly destroyed
  destroy_one(pointer, std::is_trivially_destructible{});//
}

template 
void destroy(ForwardIter first, ForwardIter last)
{
  destroy_cat(first, last, std::is_trivially_destructible<
              typename iterator_traits::value_type>{});
}
五、util 1 move和forward
function:
//function;std::move是为性能而生。
//std::move是将对象的状态或者所有权从一个对象转移到另一个对象,只是转移,没有内存的搬迁或者内存拷贝。
//用法 :
//原lvalue值被moved from之后值被转移, 所以为空字符串.
typename std::remove_reference::type&& move(T&& arg) noexcept
	{
		return std::remove_reference::type&& > (arg);
	}
example:
int main()
{
	std::string a = "shdsda";
	std::string b = std::move(a);
	std::cout << a << std::endl;
	std::cout << b << std::endl;
}//printf:a ‘空’
	template 
	T&& forward(typename std::remove_reference::type& arg) noexcept
	{
		return static_cast(arg);//
	}
	//保证右值属性
	//首先, forward常用于template函数中, 使用的时候必须要多带一个template参数T: forward, 代码略复杂;

//还有, 明确只需要move的情况而用forward, 代码意图不清晰, 其他人看着理解起来比较费劲.

//更技术上来说, 他们都可以被static_cast替代. 为什么不用static_cast呢? 也就是为了读着方便易懂.
2 pair

顾名思义:
条件判断

struct pair
{
  typedef Ty1    first_type;
  typedef Ty2    second_type;

  first_type first;    // 保存第一个数据
  second_type second;  // 保存第二个数据
  

template ::value &&
    std::is_default_constructible::value, void>::type>
    constexpr pair(): first(), second(){}//typename = typename 
    //由于第二个模板参数的类型是依赖模板lfEnableIf的嵌套类型,
    //因此您需要使用关键字typename来告诉编译器成员Type实际上是指类型而不是其他东西(即消除歧义)。//
    //同样,模板的第二个参数是无名的,但如果您愿意,可以给它命名。它不会改变任何东西
  };
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/854050.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号