revision #1: 更新第二章中已维护的代码

This commit is contained in:
Changkun Ou
2018-04-02 00:28:05 +02:00
parent 11efa38dba
commit 838d30ef5a
28 changed files with 460 additions and 111 deletions

View File

@@ -2,7 +2,7 @@
// 1.1.cpp
//
// chapter 1 introduction
// c++1x tutorial
// modern cpp tutorial
//
// created by changkun at changkun.de
//
@@ -12,7 +12,7 @@
#include <functional>
int main() {
// 使用 lambda 表达式
// use lambda expression
[out = std::ref(std::cout << "Result from C code: " << add(1, 2))](){
out.get() << ".\n";
}();

View File

@@ -2,21 +2,21 @@
# 1.1.cpp
#
# chapter 1 introduction
# c++1x tutorial
# modern cpp tutorial
#
# created by changkun at changkun.de
#
C = gcc
CXX = g++
CXX = clang++
SOURCE_C = foo.c
OBJECTS_C = foo.o
SOURCE_CXX = 1.1.cpp
SOURCE_CXX = 1.1.c.and.cpp
TARGET = 1.1
LDFLAGS_COMMON = -std=c++1z
TARGET = 1.1.out
LDFLAGS_COMMON = -std=c++17
all:
$(C) -c $(SOURCE_C)

View File

@@ -2,14 +2,14 @@
// foo.c
//
// chapter 1 introduction
// c++1x tutorial
// modern cpp tutorial
//
// created by changkun at changkun.de
//
#include "foo.h"
// C 语言代码
// C code
int add(int x, int y) {
return x+y;
}

View File

@@ -2,7 +2,7 @@
// foo.h
//
// chapter 1 introduction
// c++1x tutorial
// modern cpp tutorial
//
// created by changkun at changkun.de
//

View File

@@ -1,32 +0,0 @@
//
// 2.1.cpp
// c++1x tutorial
//
// created by changkun at changkun.de
//
// nullptr
#include <iostream>
void foo(char *);
void foo(int);
int main() {
if(NULL == (void *)0)
std::cout << "NULL == 0" << std::endl; // 该行将输出
else
std::cout << "NULL != 0" << std::endl;
foo(0); // 调用 foo(int)
//foo(NULL); // 该行不能通过编译
foo(nullptr); // 调用 foo(char*)
return 0;
}
void foo(char *ch) {
std::cout << "call foo(char*)" << std::endl;
}
void foo(int i) {
std::cout << "call foo(int)" << std::endl;
}

34
code/2/2.1.nullptr.cpp Normal file
View File

@@ -0,0 +1,34 @@
//
// 2.1.nullptr.cpp
// chapter 2 language usability
// modern cpp tutorial
//
// created by changkun at changkun.de
//
#include <iostream>
#include <type_traits>
void foo(char *);
void foo(int);
int main() {
if (std::is_same<decltype(NULL), decltype(0)>::value)
std::cout << "NULL == 0" << std::endl;
if (std::is_same<decltype(NULL), decltype((void*)0)>::value)
std::cout << "NULL == (void *)0" << std::endl;
if (std::is_same<decltype(NULL), std::nullptr_t>::value)
std::cout << "NULL == nullptr" << std::endl;
foo(0); // will call foo(int)
// foo(NULL); // doen't compile
foo(nullptr); // will call foo(char*)
return 0;
}
void foo(char *) {
std::cout << "foo(char*) is called" << std::endl;
}
void foo(int i) {
std::cout << "foo(int) is called" << std::endl;
}

View File

@@ -0,0 +1,31 @@
//
// 2.10.if.constexpr.cpp
// chapter 2 language usability
// modern cpp tutorial
//
// created by changkun at changkun.de
//
#include <iostream>
template<typename T>
auto print_type_info(const T& t) {
if constexpr (std::is_integral<T>::value) {
return t + 1;
} else {
return t + 0.001;
}
}
// at compiling time
// int print_type_info(const int& t) {
// return t + 1;
// }
// double print_type_info(const double& t) {
// return t + 0.001;
// }
int main() {
std::cout << print_type_info(5) << std::endl;
std::cout << print_type_info(3.14) << std::endl;
}

23
code/2/2.11.for.loop.cpp Normal file
View File

@@ -0,0 +1,23 @@
//
// 2.11.for.loop.cpp
// chapter 2 language usability
// modern cpp tutorial
//
// created by changkun at changkun.de
//
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
std::vector<int> vec = {1, 2, 3, 4};
if (auto itr = std::find(vec.begin(), vec.end(), 3); itr != vec.end()) *itr = 4;
for (auto element : vec)
std::cout << element << std::endl; // read only
for (auto &element : vec) {
element += 1; // writeable
}
for (auto element : vec)
std::cout << element << std::endl; // read only
}

50
code/2/2.2.constexpr.cpp Normal file
View File

@@ -0,0 +1,50 @@
//
// 2.2.constexpr.cpp
// chapter 2 language usability
// modern cpp tutorial
//
// created by changkun at changkun.de
//
#include <iostream>
#define LEN 10
int len_foo() {
int i = 2;
return i;
}
constexpr int len_foo_constexpr() {
return 5;
}
// error in c++11
// constexpr int fibonacci(const int n) {
// if(n == 1) return 1;
// if(n == 2) return 1;
// return fibonacci(n-1) + fibonacci(n-2);
// }
// ok
constexpr int fibonacci(const int n) {
return n == 1 || n == 2 ? 1 : fibonacci(n-1) + fibonacci(n-2);
}
int main() {
char arr_1[10]; // legal
char arr_2[LEN]; // legal
int len = 10;
// char arr_3[len]; // illegal
const int len_2 = len + 1;
char arr_4[len_2]; // legal
// char arr_5[len_foo()+5]; // illegal
char arr_6[len_foo_constexpr() + 1]; // legal
// 1, 1, 2, 3, 5, 8, 13, 21, 34, 55
std::cout << fibonacci(10) << std::endl;
return 0;
}

View File

@@ -1,34 +0,0 @@
//
// 2.2.cpp
// c++1x tutorial
//
// created by changkun at changkun.de
//
// constexpr
#include <iostream>
#define LEN 10
constexpr int len_foo() {
return 5;
}
constexpr int fibonacci(const int n) {
return n == 1 || n == 2 ? 1 : fibonacci(n-1)+fibonacci(n-2);
}
int main() {
char arr_1[10];
char arr_2[LEN];
const int len = 10;
char arr_3[len];
char arr_5[len_foo()+5];
std::cout << fibonacci(10) << std::endl;
// 1, 1, 2, 3, 5, 8, 13, 21, 34, 55
return 0;
}

31
code/2/2.3.if.switch.cpp Normal file
View File

@@ -0,0 +1,31 @@
//
// 2.3.if.switch.cpp
// chapter 2 language usability
// modern cpp tutorial
//
// created by changkun at changkun.de
//
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
std::vector<int> vec = {1, 2, 3, 4};
// before c++17, can be simplefied by using `auto`
const std::vector<int>::iterator itr = std::find(vec.begin(), vec.end(), 2);
if (itr != vec.end()) {
*itr = 3;
}
// after c++17, can be simplefied by using `auto`
if (const std::vector<int>::iterator itr = std::find(vec.begin(), vec.end(), 3);
itr != vec.end()) {
*itr = 4;
}
// should output: 1, 4, 3, 4. can be simplefied using `auto`
for (std::vector<int>::iterator element = vec.begin(); element != vec.end(); ++element)
std::cout << *element << std::endl;
}

View File

@@ -0,0 +1,59 @@
//
// 2.4.initializer.list.cpp
// chapter 2 language usability
// modern cpp tutorial
//
// created by changkun at changkun.de
//
#include <iostream>
#include <initializer_list>
#include <vector>
class Foo {
public:
int value_a;
int value_b;
Foo(int a, int b) : value_a(a), value_b(b) {}
};
class MagicFoo {
public:
std::vector<int> vec;
MagicFoo(std::initializer_list<int> list) {
for (std::initializer_list<int>::iterator it = list.begin(); it != list.end(); ++it) {
vec.push_back(*it);
}
}
void foo(std::initializer_list<int> list) {
for (std::initializer_list<int>::iterator it = list.begin(); it != list.end(); ++it) {
vec.push_back(*it);
}
}
};
int main() {
// before C++11
int arr[3] = {1, 2, 3};
Foo foo(1, 2);
std::vector<int> vec = {1, 2, 3, 4, 5};
// after C++11
MagicFoo magicFoo = {1, 2, 3, 4, 5};
magicFoo.foo({6,7,8,9});
Foo foo2 {3, 4};
std::cout << "arr[0]: " << arr[0] << std::endl;
std::cout << "foo:" << foo.value_a << ", " << foo.value_b << std::endl;
std::cout << "vec: ";
for (std::vector<int>::iterator it = vec.begin(); it != vec.end(); ++it) {
std::cout << *it << std::endl;
}
std::cout << "magicFoo: ";
for (std::vector<int>::iterator it = magicFoo.vec.begin(); it != magicFoo.vec.end(); ++it) {
std::cout << *it << std::endl;
}
std::cout << "foo2: " << foo2.value_a << ", " << foo2.value_b << std::endl;
return 0;
}

View File

@@ -1,34 +0,0 @@
//
// 2.5.cpp
// c++1x tutorial
//
// created by changkun at changkun.de
//
// 初始化列表
#include <initializer_list>
class Foo {
private:
int value;
public:
Foo(int) {}
};
class Magic {
public:
Magic(std::initializer_list<int> list) {}
};
void func(std::initializer_list<int> list) {
return;
}
int main() {
int arr[3] = {1,2,3}; // 列表初始化
Foo foo(1); // 普通构造初始化
Magic magic = {1,2,3,4,5}; // 使用 initialize_list
func({1,2,3});
}

View File

@@ -0,0 +1,20 @@
//
// 2.5.structured.binding.cpp
// chapter 2 language usability
// modern cpp tutorial
//
// created by changkun at changkun.de
//
#include <iostream>
#include <string>
std::tuple<int, double, std::string> f() {
return std::make_tuple(1, 2.3, "456");
}
int main() {
auto [x, y, z] = f();
std::cout << x << ", " << y << ", " << z << std::endl;
return 0;
}

42
code/2/2.6.auto.cpp Normal file
View File

@@ -0,0 +1,42 @@
//
// 2.6.auto.cpp
// chapter 2 language usability
// modern cpp tutorial
//
// created by changkun at changkun.de
//
#include <initializer_list>
#include <vector>
#include <iostream>
class MagicFoo {
public:
std::vector<int> vec;
MagicFoo(std::initializer_list<int> list) {
for (auto it = list.begin(); it != list.end(); ++it) {
vec.push_back(*it);
}
}
};
// wrong
// int add(auto x, auto y) {
// return x+y;
// }
int main() {
MagicFoo magicFoo = {1, 2, 3, 4, 5};
std::cout << "magicFoo: ";
for (auto it = magicFoo.vec.begin(); it != magicFoo.vec.end(); ++it) {
std::cout << *it << ", ";
}
std::cout << std::endl;
auto i = 5; // type int
auto j = 6; // type int
auto arr = new auto(10); // type int*
// auto auto_arr2[10] = arr;
// std::cout << add(i, j) << std::endl;
return 0;
}

23
code/2/2.7.decltype.cpp Normal file
View File

@@ -0,0 +1,23 @@
//
// 2.7.decltype.cpp
// chapter 2 language usability
// modern cpp tutorial
//
// created by changkun at changkun.de
//
#include <iostream>
#include <type_traits>
int main() {
auto x = 1;
auto y = 2;
decltype(x+y) z = 3;
if (std::is_same<decltype(x), int>::value)
std::cout << "type x == int" << std::endl;
if (std::is_same<decltype(x), float>::value)
std::cout << "type z == float" << std::endl;
if (std::is_same<decltype(x), decltype(z)>::value)
std::cout << "type z == type x" << std::endl;
return 0;
}

View File

@@ -0,0 +1,46 @@
//
// 2.8.tail.return.type.cpp
// chapter 2 language usability
// modern cpp tutorial
//
// created by changkun at changkun.de
//
#include <iostream>
#include <type_traits>
// before c++11
template<typename R, typename T, typename U>
R add(T x, U y) {
return x + y;
}
// after c++11
template<typename T, typename U>
auto add2(T x, U y) -> decltype(x+y){
return x + y;
}
// after c++14
template<typename T, typename U>
auto add3(T x, U y){
return x + y;
}
int main() {
// before c++11
int z = add<int, int, int>(1, 2);
std::cout << z << std::endl;
// after c++11
auto w = add2<int, double>(1, 2.0);
if (std::is_same<decltype(w), double>::value) {
std::cout << "w is double: ";
}
std::cout << w << std::endl;
// after c++14
auto q = add3<double, int>(1.0, 2);
std::cout << "q: " << q << std::endl;
return 0;
}

View File

@@ -0,0 +1,21 @@
//
// 2.9.decltype.auto.cpp
// chapter 2 language usability
// modern cpp tutorial
//
// created by changkun at changkun.de
//
template<int i>
struct Int {};
constexpr auto iter(Int<0>) -> Int<0>;
template<int i>
constexpr auto iter(Int<i>) {
return iter(Int<i-1>{});
}
int main() {
decltype(iter(Int<10>{})) a;
}

7
code/2/Makefile Normal file
View File

@@ -0,0 +1,7 @@
all: $(patsubst %.cpp, %.out, $(wildcard *.cpp))
%.out: %.cpp Makefile
clang++ $< -o $@ -std=c++17
clean:
rm *.out

View File

@@ -32,7 +32,7 @@ int main() {
int arr[10] = {0};
auto auto_arr = arr; // 正确,对整个类型进行推导
//auto auto_arr2[10] = arr; // 错误, 无法推导数组元素类型
// auto auto_arr2[10] = arr; // 错误, 无法推导数组元素类型
auto x = 1;
auto y = 2;

21
code/2/todo/2.xxx.cpp Normal file
View File

@@ -0,0 +1,21 @@
#include <iostream>
template<typename T0>
void printf(T0 value) {
std::cout << value << std::endl;
}
template<typename T, typename... Args>
void printf(T value, Args... args) {
std::cout << value << std::endl;
printf(args...);
}
template<typename T0, typename... T>
void printf_short(T0 t0, T... t) {
std::cout << t0 << std::endl;
if constexpr (sizeof...(t) > 0) printf(t...);
}
int main() {
printf_short(1, 2, "123", 1.1);
return 0;
}

View File

@@ -0,0 +1,8 @@
#include <iostream>
template<typename ... T>
auto sum(T ... t) {
return (t + ...);
}
int main() {
std::cout << sum(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) << std::endl;
}