BruceChen7 / gitblog

My blog
6 stars 1 forks source link

Cpp11基本知识 #30

Open BruceChen7 opened 3 years ago

BruceChen7 commented 3 years ago

参考资料

image

统一初始化

int  x1(5.3); // 5
int x2 = 5.3 //5
int xi{5.0} // 所以会出现error
int x4 = {5.3} // 会出现error
char ci{7};   
char c9{9999}; // 9999不合适是一个char类型

class Widget{
    ...
private:
    int x{0};       //没问题,x初始值为0
    int y = 0;      //同上
    int z(0);       //错误!
}
// sp的类型为std::shared<int>
auto sp = std::make_shared<int>(new int(10)); 
auto ar = { 1, 2, 3 };  // ar 是一个std::initializer_list<int>类型

std::vector<int> vec;
vec.push_back(1);
auto iter = a.begin();
auto fn = [](int a) { return a + 1; } // 定义一个lambda表达式

template<typename Container,typename Index>
auto authAndAccess(Container& c,Index i)->decltype(c[i])
{
    authenticateUser();
    return c[i];
}

类型推导

auto a = 3.14; // double
auto b = 1; // int
auto& c = b; // int&
auto d = { 0 }; // std::initializer_list<int>
auto&& e = 1; // int&&
auto&& f = b; // int&
auto g = new auto(123); // int*
const auto h = 1; // const int
auto i = 1, j = 2, k = 3; // int, int, int
auto l = 1, m = true, n = 1.61; // error -- `l` deduced to be int, `m` is bool
auto o; // error -- `o` requires initializer

类型推导

auto x = 27;
const auto cx = x;
const auto & rx=cx;

template<typename T>    // 理想化的模板用来推导x的类型
void func_for_x(T param);
func_for_x(27);

template<typename T>    //理想化的模板用来推导cx 的类型
void func_for_cx(const T param);
func_for_cx(x);

template<typename T>    //理想化的模板用来推导rx的类型
void func_for_rx(const T & param);
func_for_rx(x);

类型推导

const char name[] =     //name的类型是const char[13]
 "R. N. Briggs";

auto arr1 = name;       //arr1的类型是const char*
auto& arr2 = name;      //arr2的类型是const char(&)[13]

void someFunc(int, double);

auto func1=someFunc;    //func1的类型是void(int,double)
auto& func2 = someFunc; //func2的类型是void(&)(int,double)

nullptr

void foo(int);
void foo(char*);
foo(NULL); // error -- ambiguous
foo(nullptr); // calls foo(char*)

类型安全的枚举

// Specifying underlying type as `unsigned int`
enum class Color : unsigned int { 
    Red = 0xff0000, 
    Green = 0xff00, 
    Blue = 0xff 
};
// `Red`/`Green` in `Alert` don't conflict with `Color`
enum class Alert : bool { 
    Red,
    Green
};
Color c = Color::Red;

Default functions and deleted functions

struct A {
  A() = default;
  A(int x) : x{x} {}
  int x {1};
};
A a; // a.x == 1
A a2 {123}; // a.x == 123

Default functions and deleted functions

class A {
  int x;

public:
  A(int x) : x{x} {};
  A(const A&) = delete;
  A& operator=(const A&) = delete;
};

A x {123};
A y = x; // error -- call to deleted copy constructor
y = x; // error -- operator= deleted

Explicit virtual overrides

struct A {
  virtual void foo();
  void bar();
};

struct B : A {
  void foo() override; // correct -- B::foo overrides A::foo
  void bar() override; // error -- A::bar is not virtual
  void baz() override; // error -- B::baz does not override A::baz
};

final specifier

struct A {
  virtual void foo();
};

struct B : A {
  virtual void foo() final;
};

struct C : B {
  virtual void foo(); // error -- declaration of 'foo' overrides a 'final' function
};

struct A final {};
struct B : A {}; // error -- base 'A' is marked 'final'

ranged based for loops

for (const auto& kv : myMap) {
    std::cout << kv.first << " has value " << kv.second << std::endl;
}

std::array<int, 5> a {1, 2, 3, 4, 5};
for (int& x : a) x *= 2;
// a == { 2, 4, 6, 8, 10 }

std::array<int, 5> a {1, 2, 3, 4, 5};
for (int x : a) x *= 2;
// a == { 1, 2, 3, 4, 5 }

左值与右值

左值与右值

移动与完美转发

std::move 示例代码:

std::forward解决的问题:

移动与完美转发实现

template <class T>
typename remove_reference<T>::type&&
move(T&& a)
{
    return a;
}

template <class T>
struct identity
{
    typedef T type;
};

template <class T>
T&& forward(typename identity<T>::type&& a)
{
    return a;
}

通用引用(T&&)和右值引用

void f(Widget&& param);     //右值引用
Widget&& var1 = Widget();   //右值引用
auto&& var2 = var1;         //不是右值引用

template <typename T>
void f(std::vector<T>&& param); //右值引用

template <typename T>
void f(T&& param);          //不是右值引用

通用引用(T&&)和右值引用

template <typename T>
void f(T&& param);              //param是一个通用引用

Widget w;
f(w);                           //传递给函数f一个左值;参数param的类型
                                //将会是Widget&,也即左值引用

f(std::move(w));                //传递给f一个右值;参数param的类型会是
                                //Widget&&,即右值引用

闭包

int x = 1;
auto getX = [=] { return x; };
getX(); // == 1

auto addX = [=](int y) { return x + y; };
addX(1); // == 2

auto getXRef = [&]() -> int& { return x; };
getXRef(); // int& to `x`

闭包

闭包

int x = 1;
// OK: x is a reference and modifies the original
auto f1 = [&x] { x = 2; }; 
// ERROR: 
// the lambda can only perform const-operations on the captured value
auto f2 = [x] { x = 2; }; 
// OK: the lambda can perform any operations on the captured value
auto f3 = [x]() mutable { x = 2; }; 
[&tota, offset](X& elem) {total += elem.get() + offset;}

class _SomeCOmpilerGeneratedName_ {
public:
   _SomeCOmpilerGeneratedName_(int& t, int o): total_(t), offset_(o) {}
   void operator()(X& elem) const { total_ += elem.getVal() + offset_; }
private:
  int& total_;
  int offset_;
};
std::unique_ptr<Foo> p1 {new Foo{}};  // `p1` owns `Foo`
if (p1) {
  p1->bar();
}

{
  std::unique_ptr<Foo> p2 {std::move(p1)};  // Now `p2` owns `Foo`
  f(*p2);

  p1 = std::move(p2);  // Ownership returns to `p1` -- `p2` gets destroyed
}
// `Foo` instance is destroyed when `p1` goes out of scope

智能指针

int *ip = new int;
// 不要这样做
shared_ptr<int> sp1(ip);
shared_ptr<int> sp2(ip);

struct S
{
  shared_ptr<S> dangerous()
  {
     return shared_ptr<S>(this);   // don't do this!
  }
};

int main()
{
   shared_ptr<S> sp1(new S);
   shared_ptr<S> sp2 = sp1->dangerous();
   return 0;
}

智能指针

struct S : enable_shared_from_this<S>
{
  shared_ptr<S> not_dangerous()
  {
    return shared_from_this();
  }
};

int main()
{
   shared_ptr<S> sp1(new S);
   shared_ptr<S> sp2 = sp1->not_dangerous();
   return 0;
}

智能指针

std::array

std::array<int, 3> a = {2, 1, 3};
std::sort(a.begin(), a.end()); // a == { 1, 2, 3 }
for (int& x : a) x *= 2; // a == { 2, 4, 6 }

std::tuples

// `playerProfile` has type `std::tuple<int, const char*, const char*>`.
auto playerProfile = std::make_tuple(51, "Frans Nielsen", "NYI");
std::get<0>(playerProfile); // 51
std::get<1>(playerProfile); // "Frans Nielsen"
std::get<2>(playerProfile); // "NYI"

unordered 容器

未完待续的东西