现代c++笔记(1)

variadic templates(数量不定的模板参数)
//递归定义
void printX() {} //递归终止条件
//接受任意个数任意类型参数
template<typename T,typename... Types>
void printX(const T& firstarg, const Types&... args)
{
  cout << firstarg << endl;
  //sizeof...(args) //查看pack的args的个数
  printX(args...);
})
 //泛化 上述特化,编译器优先选择特化版本
template<typename... Types>
void printX(const Types&... args)
{
  //...
}
//递归继承
template<typename Head,typename... Tail>
class Tuple<Head,Tail...>
  :private Tuple<Tail...>
  {
    protected:
      Head m_head;
  }
nullptr

c++11 使用nullptr替代NULL(0),主要是为了避免pointer和int歧义

void f(int); //fun1
void f(void*);//fun2
f(0);//call  fun1
f(NULL);    //编译不过歧义 vs2019可以编译过 call fun1
f(nullptr);//call fun2
auto

编译器可以自动推倒类型,主要方便简化代码或者避免写太复杂类型

auto a = 2.3;
double f();
auto b = f();
vector<string> v;
auto pos = v.begin();  
auto l = [](int x)->bool { //int 参数 返回bool l为一个lambda
  ...
}
Uniform initialization
//c++ 11之前的几种写法
Rect r1 = {3,7,20,25,&area,&print}
Rect r1(3,7,20,25);
int ia[6] = {3,7,20,25};
//由于c++之前多种初始化写法,所以c++引入一致性初始化 变量后直接都用大括弧
//{}下的东西 做出一个initializer_list<T>,关联一个array<T,n>
//如果构造函数中本身接受的参数为initializer_list<T>,那么直接可以传递这个参数过去
//否则编译器会依次拆分传递给构造函数
int values[]{1,2,3};
vector<int> v{1,2,3};
complex<double> c{2.3,3.4};
vector<string> vs{"aa","bb"};
initializer Lists
 //设置初始值
int a{};
int*p{};
//转换
int a(5.3);//double->int a=5
int a{5.0};//编译不通过 提示:double到int收缩转换 也可能给warning
int a= {5.0};//编译不通过
char c1{7};
char c1{9999};//编译不通过
//
void print(std::initializer_list<int> vals)
{
  for (auto i = vals.begin();i != vals.end();++i)
    cout<<*i<<endl;
}
print({2,4,7};)
class P{
  public:
    P(int a,int b)
    {
      cout<<"P(int a,int b)"<<a<<b<<endl;
    }
  //如果没有这个版本,编译器会自动拆分,调用到上述的版本
  //编译器首先会自动生成array,然后构造initializer_list,所以initializer_list中有个成员作为持有array的指针
    P(initializer_list<int> initlist){
      cout<<"initializer_list";
      for (auto p : initlist)
        cout<<p;
      cout<<endl;
    }
}
P p1(2,3);//call P(int a,int b)
P p2{2,3};//call initializer
P s = {2,3};//call initializer
array-作为initializer_list成员变量的指向
template <typename _Tp,std::size_t _Nm>
struct array {
  typedef _Tp value_type;
  typedef _Tp* pointer;
  typedef value_type* iterator;
  value_type _M_instance[_Nm ? _Nm:1];//如果传递0,默认长度给1
  iterator begin(){
    return iterator(&_M_instance[0]);
  }
  iterator end(){
    return iterator(&_M_instance[_Nm]);
  } 
}
标准库中使用initializer_list

标准库中大量使用initializer_list, 不仅仅是各种容器的构造函数,拷贝构造函数,以及赋值重载函数,甚至算法库也用到了

template<typename _Tp>
inline _Tp min(initializer_list<_Tp> _l){
  return *std::min_element(_l.begin(),_l.end());
}
//用法,这样可以不止传递两个参数作为min的参数了
cout<<min({1,3,5});
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 一、C语言基础 1、struct 的内存对齐和填充问题其实只要记住一个概念和三个原则就可以了: 一个概念:自然对齐...
    XDgbh阅读 2,350评论 1 38
  • C++演化是从c++98(1.0)到c++03到c++11(2.0)到c++14,当然后面不断更新。从1.0到2....
    涤除而玄览阅读 198评论 0 0
  • 前言 把《C++ Primer》[https://book.douban.com/subject/25708312...
    尤汐Yogy阅读 9,688评论 1 51
  • 这篇文章以《C++ Primer》(第五版)为基础,结合自己的理解,将C++11的新特性加以总结、概括,以加深印象...
    n411阅读 952评论 2 6
  • C++ 标准库的接口由下列头文件的汇集定义。 概念库 <concepts>[https://www.apiref....
    ixiaoyang8阅读 981评论 0 0

友情链接更多精彩内容