mirror of
https://github.com/changkun/modern-cpp-tutorial.git
synced 2025-12-18 05:04:39 +03:00
revision #1: 更新第二章中已维护的代码
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -27,3 +27,6 @@
|
|||||||
*.exe
|
*.exe
|
||||||
*.out
|
*.out
|
||||||
*.app
|
*.app
|
||||||
|
|
||||||
|
node_modules
|
||||||
|
website/public
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
// 1.1.cpp
|
// 1.1.cpp
|
||||||
//
|
//
|
||||||
// chapter 1 introduction
|
// chapter 1 introduction
|
||||||
// c++1x tutorial
|
// modern cpp tutorial
|
||||||
//
|
//
|
||||||
// created by changkun at changkun.de
|
// created by changkun at changkun.de
|
||||||
//
|
//
|
||||||
@@ -12,7 +12,7 @@
|
|||||||
#include <functional>
|
#include <functional>
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
// 使用 lambda 表达式
|
// use lambda expression
|
||||||
[out = std::ref(std::cout << "Result from C code: " << add(1, 2))](){
|
[out = std::ref(std::cout << "Result from C code: " << add(1, 2))](){
|
||||||
out.get() << ".\n";
|
out.get() << ".\n";
|
||||||
}();
|
}();
|
||||||
@@ -2,21 +2,21 @@
|
|||||||
# 1.1.cpp
|
# 1.1.cpp
|
||||||
#
|
#
|
||||||
# chapter 1 introduction
|
# chapter 1 introduction
|
||||||
# c++1x tutorial
|
# modern cpp tutorial
|
||||||
#
|
#
|
||||||
# created by changkun at changkun.de
|
# created by changkun at changkun.de
|
||||||
#
|
#
|
||||||
|
|
||||||
C = gcc
|
C = gcc
|
||||||
CXX = g++
|
CXX = clang++
|
||||||
|
|
||||||
SOURCE_C = foo.c
|
SOURCE_C = foo.c
|
||||||
OBJECTS_C = foo.o
|
OBJECTS_C = foo.o
|
||||||
|
|
||||||
SOURCE_CXX = 1.1.cpp
|
SOURCE_CXX = 1.1.c.and.cpp
|
||||||
|
|
||||||
TARGET = 1.1
|
TARGET = 1.1.out
|
||||||
LDFLAGS_COMMON = -std=c++1z
|
LDFLAGS_COMMON = -std=c++17
|
||||||
|
|
||||||
all:
|
all:
|
||||||
$(C) -c $(SOURCE_C)
|
$(C) -c $(SOURCE_C)
|
||||||
|
|||||||
@@ -2,14 +2,14 @@
|
|||||||
// foo.c
|
// foo.c
|
||||||
//
|
//
|
||||||
// chapter 1 introduction
|
// chapter 1 introduction
|
||||||
// c++1x tutorial
|
// modern cpp tutorial
|
||||||
//
|
//
|
||||||
// created by changkun at changkun.de
|
// created by changkun at changkun.de
|
||||||
//
|
//
|
||||||
|
|
||||||
#include "foo.h"
|
#include "foo.h"
|
||||||
|
|
||||||
// C 语言代码
|
// C code
|
||||||
int add(int x, int y) {
|
int add(int x, int y) {
|
||||||
return x+y;
|
return x+y;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
// foo.h
|
// foo.h
|
||||||
//
|
//
|
||||||
// chapter 1 introduction
|
// chapter 1 introduction
|
||||||
// c++1x tutorial
|
// modern cpp tutorial
|
||||||
//
|
//
|
||||||
// created by changkun at changkun.de
|
// created by changkun at changkun.de
|
||||||
//
|
//
|
||||||
|
|||||||
@@ -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
34
code/2/2.1.nullptr.cpp
Normal 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;
|
||||||
|
}
|
||||||
31
code/2/2.10.if.constexpr.cpp
Normal file
31
code/2/2.10.if.constexpr.cpp
Normal 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
23
code/2/2.11.for.loop.cpp
Normal 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
50
code/2/2.2.constexpr.cpp
Normal 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;
|
||||||
|
}
|
||||||
@@ -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
31
code/2/2.3.if.switch.cpp
Normal 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;
|
||||||
|
}
|
||||||
59
code/2/2.4.initializer.list.cpp
Normal file
59
code/2/2.4.initializer.list.cpp
Normal 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;
|
||||||
|
}
|
||||||
@@ -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});
|
|
||||||
}
|
|
||||||
20
code/2/2.5.structured.binding.cpp
Normal file
20
code/2/2.5.structured.binding.cpp
Normal 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
42
code/2/2.6.auto.cpp
Normal 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
23
code/2/2.7.decltype.cpp
Normal 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;
|
||||||
|
}
|
||||||
46
code/2/2.8.tail.return.type.cpp
Normal file
46
code/2/2.8.tail.return.type.cpp
Normal 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;
|
||||||
|
}
|
||||||
21
code/2/2.9.decltype.auto.cpp
Normal file
21
code/2/2.9.decltype.auto.cpp
Normal 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
7
code/2/Makefile
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
all: $(patsubst %.cpp, %.out, $(wildcard *.cpp))
|
||||||
|
|
||||||
|
%.out: %.cpp Makefile
|
||||||
|
clang++ $< -o $@ -std=c++17
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm *.out
|
||||||
@@ -32,7 +32,7 @@ int main() {
|
|||||||
|
|
||||||
int arr[10] = {0};
|
int arr[10] = {0};
|
||||||
auto auto_arr = arr; // 正确,对整个类型进行推导
|
auto auto_arr = arr; // 正确,对整个类型进行推导
|
||||||
//auto auto_arr2[10] = arr; // 错误, 无法推导数组元素类型
|
// auto auto_arr2[10] = arr; // 错误, 无法推导数组元素类型
|
||||||
|
|
||||||
auto x = 1;
|
auto x = 1;
|
||||||
auto y = 2;
|
auto y = 2;
|
||||||
21
code/2/todo/2.xxx.cpp
Normal file
21
code/2/todo/2.xxx.cpp
Normal 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;
|
||||||
|
}
|
||||||
8
code/2/todo/fold.expression.cpp
Normal file
8
code/2/todo/fold.expression.cpp
Normal 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;
|
||||||
|
}
|
||||||
8
exercises/2/fold.expresion.cpp
Normal file
8
exercises/2/fold.expresion.cpp
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
#include <iostream>
|
||||||
|
template<typename ... T>
|
||||||
|
auto average(T ... t) {
|
||||||
|
return (t + ... ) / sizeof...(t);
|
||||||
|
}
|
||||||
|
int main() {
|
||||||
|
std::cout << average(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) << std::endl;
|
||||||
|
}
|
||||||
22
exercises/2/structured.binding.cpp
Normal file
22
exercises/2/structured.binding.cpp
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
#include <iostream>
|
||||||
|
#include <map>
|
||||||
|
#include <string>
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
|
template <typename Key, typename Value, typename F>
|
||||||
|
void update(std::map<Key, Value>& m, F foo) {
|
||||||
|
for (auto&& [key, value] : m ) value = foo(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
std::map<std::string, long long int> m {
|
||||||
|
{"a", 1},
|
||||||
|
{"b", 2},
|
||||||
|
{"c", 3}
|
||||||
|
};
|
||||||
|
update(m, [](std::string key) -> long long int {
|
||||||
|
return std::hash<std::string>{}(key);
|
||||||
|
});
|
||||||
|
for (auto&& [key, value] : m)
|
||||||
|
std::cout << key << ":" << value << std::endl;
|
||||||
|
}
|
||||||
0
exercises/2/variadic.template.parameter.pack.cpp
Normal file
0
exercises/2/variadic.template.parameter.pack.cpp
Normal file
Reference in New Issue
Block a user