文章目录
需要注意的赋值,拷贝,复制,移动的含义
拷贝构造(
原来的东西不存在,需要先创建对象)A(const A& rhs)
A a = 123;
赋值构造(原来的东西存在的,内容被覆盖)A& operator=(const A& rhs)
A a;
B b(123);
a = b;
auto类型推导
初始化一个变量的时候使用
decltype获取表达式类型
返回类型后置(auto, decltype)
template <typename T, typename U>
auto add(T t, U u) -> decltype(t + u)
{
return t + u;
}
模板的别名using
1、typedef 不能定义模板
2、using的别名语法完全覆盖了typedef的全部功能
template<typename T>
using Str_Map_Any = std::map<std::tring, T>;
Str_Map_Any<int> strMapInt;
Str_Map_Any<double> strMapDouble;
Str_Map_Any<float> strMapFloat;
初始化列表(或叫列表初始化)
使用列表初始化的时候, {}前面的等号写不写都是可以的
列表初始,不仅统一了 各种对象的初始化方式,而且还是代码的书写变得更加的简单清晰。
class Foo
{
public:
Foo(int) {}
private:
Foo(const Foo &); // 拷贝构造, Foo a = b; 时调用
Foo& operator=(const Foo &); // 赋值构造, a = b; 时调用
};
int main(void)
{
Foo a1(123);
Foo a2 = 123; // error, 拷贝构造是私有的
Foo a3 = {123}; // ok, 列表初始化,调用的构造函数,私有的拷贝构造函数影响不了它
Foo a3 {123}; // ok, 使用列表初始化的时候, {}前面的等号写不写都是可以的
}
列表初始可以用在函数的返回值上
return {12, 12};
std::initializer_list
int arr[] {1, 2, 3};
std::set<int> ss {1, 2, 3, 4, 5, 6};
std::vector<int> arr {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
我们发现初始化的时候,没有指明长度,那么初始化列表可是任何长度的,那么他的底层是怎么实现的呢?
{…} 是通过使用std::initializer_list这个轻量级类模板来实现上述功能支持的。
STL的内置模板类都是支持初始化列表的,那我们的自定义类型怎么支持初始化列表呢?
std::initialiazer_list是用来接收{…}
class Foo
{
public:
Foo(std::initializer_list<inst>) {}
};
Foo foo {1, 2, 3, 4}; // ok
///
class FooVector
{
std::vector<int> content;
public:
FooVector(std::initializer_list<int> list) {
for(auto it = list.bengin(); it != list.end(); ++it) {
content.push_back(*it);
}
}
;
FooVector foo1 {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; // ok
///
class FooMap
{
std::map<int, int> content;
using pair_t = std::map<int, int>::value_type;
public:
FooMap(std::initializer_list<pair_t > list) {
for(auto it = list.bengin(); it != list.end(); ++it) {
content.inster(*it);
}
}
};
FooMap foo2 {{1,3}, {2, 3}, {3, 4}} // ok
std::initializer_list 有三个成员函数begin(), end(), size();
std::initialiazer_list中,不能修改某个元素的值,但是可以整体修改
std::initializer_list<int> list;
size_t n = list.size(); // n == 0
list = {1, 2, 3, 4, 5, 6};
size_t n = list.size(); // n == 6
list = {1};
size_t n = list.size(); // n == 1
需要注意的是,std::initialiazer_list并不负责保存初始化列表的拷贝,它仅仅是存储了列表中元素的引用而已;
列表初始化,还有 防止类型窄化的作用
基于范围的for的循环 (range-based for)
for (auto items : data) {
}
std::bind 函数绑定器
std::bind的返回值是STL里面的仿函数对象;
std::bind什么可调用对象都可以绑定,包括类成员(函数);
std::bind可以绑定多个可调用对象;
using std::placeholders::_1;
auto f = std::bind(std::logic_and<bool>(),
std::bind(std::less<int>(), _1, 10),
std::bind(std::greater<int>(), _1, 5))
std::count_if(coll.begin(), coll.end(), f);
// 使用lamda表达式的话,就很简洁
auto f = std::count_if(coll.begin().coll.end(), [](int x) {
return x < 10 && x > 5;
});
右值引用(&&)
移动语义(std::move)
完美转发 (std::forward)
常用连接
类型萃取
qicosmos/cosmos