ghostbody / 15-cpp-learning

15 c++ learning repository of SDCS SYSU
6 stars 3 forks source link

C++ 11-15 Features Notes (1) #9

Open ghostbody opened 8 years ago

ghostbody commented 8 years ago

We are building a project using C++ 11. The features of C++11 is quite surprising. However, it's so disappointing that Eden does not support C++11. I am learning it now and there are some features in this issue.

C++ 11 Catalog (which I think they are important)

  1. Rvalue references and move constructors
  2. constexpr – Generalized constant expressions
  3. Modification to the definition of plain old data
  4. Extern template
  5. Initializer lists
  6. Uniform initialization
  7. Type inference(auto)
  8. Range-based for loop
  9. Lambda functions and expressions
  10. Multithreading memory model

    Keyword : auto

If you have used python or swift of javascript or other 'loose data type' language, the compiler or interpreter will deduction the type of the data automatically. For example in python:

a = 100 # integer type
b = 100.0 # float type
c = "abcde" # string 
d = open("./x.txt", "r") # file handler

However, on the contrary, we know that, c++ is a kind of 'strict' type language which means that the compiler request datatype when you declare the variable. It's in C++ 11 that key word 'auto' make it awesome for auto data types.

auto a = "123";
auto b = 10.0;
auto c = {1, 2};

The compiler of C++11 standard can deduction the data type automatically, too. You can try it yourself. And we can get type information using the following example:

#include <typeinfo>
#include <iostream>

using namespace std;

int main() {
  auto x = 1.0;
  auto y = "abcde";
  auto z = {1,2,3,4};
  cout << typeid(x).name() << endl;
  cout << typeid(y).name() << endl;
  cout << typeid(z).name() << endl;
  return 0;
}

typeid is a C++ language operator which returns type identification information at run time. It basically returns a type_info object, which is equality-comparable with other type_info objects.

Lambda Function

Also, in some language, especially in javascript, lambda function is very common.

x = function (a, b){return a+b};
x(1,2);

In C++11, lambda function is provided and it's very useful to replace annoying function pointers.

Example:

#include <iostream>
#include <list>

int main() {
  std::list<int> li = { 1,2,3,4,5,6,7,8 };
  for(std::list<int>::iterator it = li.begin();
      it != li.end(); it++) {
    std::cout << *it << " ";
  }
  std::cout << std::endl;
  li.remove_if([&](int x) -> bool {
      if(x % 2 == 0) {
    return true;
      }
      return false;
  });
  for(std::list<int>::iterator it = li.begin();
      it != li.end(); it++) {
    std::cout << *it << " ";
  }
  std::cout << std::endl;
  return 0;
}

Output:

1 2 3 4 5 6 7 8 
1 3 5 7

Well, there is also a equal one:

#include <iostream>
#include <list>
#include <algorithm>

int main() {
  std::list<int> li = { 1,2,3,4,5,6,7,8 };
  std::for_each(li.begin(), li.end(), [](int x){std::cout << x << " ";});
  std::cout << std::endl;
  li.remove_if([&](int x) -> bool { return x % 2 == 0;});
  std::for_each(li.begin(), li.end(), [](int x){std::cout << x << " ";});
  std::cout << std::endl;
  return 0;
}

What is the answer of this? :100: :smile:

int x = 4;
auto y = [&r = x, x = x + 1]()->int
    {
        r += 2;
        return x + 2;
    }();

We will get error when we use auto in parameters in C++11, but it work in C++14:

#include <iostream>
#include <list>
#include <algorithm>

int main() {
  std::list<int> li1 { 1,2,3,4,5,6,7,8 };
  std::list<double> li2 { 1.1,2.2,3.3,4.4,5.5,6.6,7.7,8.8 };
  auto traversal = [](auto && list) {
    for(auto x : list)
      std::cout << x << " ";
    std::cout << std::endl;
  };
  traversal(li1);
  traversal(li2);
  return 0;
}

unique_ptr (智能指针,无须程序员手动delete堆内存,在恰当时机自动delete)

We will get into trouble if we have the following code:

int * a = new int [100];
a = NULL;
return 0;

Oh! Memory leak will occur if we write this code. But unique_pointer helps us to manage memory automatically.

#include <memory>

int main() {
  std::unique_ptr<int> a (new int[100]);
  return 0;
}

You can test it using 'valgrind', but a mismatched error will still reported with no memory leak.

Range Base Loop

#include <iostream>
#include <vector>

int main() {
  vector<int> a {1,2,3,4,5,6,7,8};
  for(auto i : a) {
    std::cout << i << " ";
  }
  std::cout << endl;
  return 0;              
}

quite convenient to use this kind of for loop somewhere

Compiler

Remember to add -std=c++11 or -std=c++14 or -std=c++15 when you are trying to compile the code.

If you have any question, idea or some experience for learning c++11 - c++15, you can make an issue or comment here.

Hope you learn something.

Happy coding.