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});
网友评论