mirror of
https://github.com/changkun/modern-cpp-tutorial.git
synced 2025-12-17 04:34:40 +03:00
prepare for c++17
This commit is contained in:
32
code/2/2.1.cpp
Normal file
32
code/2/2.1.cpp
Normal file
@@ -0,0 +1,32 @@
|
||||
//
|
||||
// 2.1.cpp
|
||||
// c++1x tutorial
|
||||
//
|
||||
// created by changkun at shiyanlou.com
|
||||
//
|
||||
// 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.2.cpp
Normal file
34
code/2/2.2.cpp
Normal file
@@ -0,0 +1,34 @@
|
||||
//
|
||||
// 2.2.cpp
|
||||
// c++1x tutorial
|
||||
//
|
||||
// created by changkun at shiyanlou.com
|
||||
//
|
||||
// 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;
|
||||
}
|
||||
49
code/2/2.3.cpp
Normal file
49
code/2/2.3.cpp
Normal file
@@ -0,0 +1,49 @@
|
||||
//
|
||||
// 2.3.cpp
|
||||
// c++1x tutorial
|
||||
//
|
||||
// created by changkun at shiyanlou.com
|
||||
//
|
||||
// auto/decltype/尾返回类型/返回类型推导
|
||||
|
||||
|
||||
#include <iostream>
|
||||
|
||||
// 传统 C++
|
||||
template <typename R, typename T, typename U>
|
||||
R add1(T x, U y) {
|
||||
return x+y;
|
||||
}
|
||||
|
||||
// 尾返回类型
|
||||
template <typename T, typename U>
|
||||
auto add2(T x, U y) -> decltype(x+y) {
|
||||
return x+y;
|
||||
}
|
||||
|
||||
// C++14 返回类型推导
|
||||
template <typename T, typename U>
|
||||
auto add3(T x, U y) {
|
||||
return x+y;
|
||||
}
|
||||
|
||||
int main() {
|
||||
auto i = 5;
|
||||
|
||||
int arr[10] = {0};
|
||||
auto auto_arr = arr; // 正确,对整个类型进行推导
|
||||
//auto auto_arr2[10] = arr; // 错误, 无法推导数组元素类型
|
||||
|
||||
auto x = 1;
|
||||
auto y = 2;
|
||||
decltype(x+y) z1;
|
||||
//auto z2; // 错误, 无法推导
|
||||
|
||||
|
||||
std::cout << add1<int, int, int>(1,1) << std::endl;
|
||||
std::cout << add1<int, int>(1,1) << std::endl;
|
||||
std::cout << add1<int, int>(1,1) << std::endl;
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
30
code/2/2.4.cpp
Normal file
30
code/2/2.4.cpp
Normal file
@@ -0,0 +1,30 @@
|
||||
//
|
||||
// 2.4.cpp
|
||||
// c++1x tutorial
|
||||
//
|
||||
// created by changkun at shiyanlou.com
|
||||
//
|
||||
// 区间迭代
|
||||
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
int main() {
|
||||
int array[] = {1,2,3,4,5};
|
||||
for(auto &x : array) {
|
||||
std::cout << x << std::endl;
|
||||
}
|
||||
|
||||
// 传统 C++ 写法
|
||||
std::vector<int> arr(5, 100);
|
||||
for(std::vector<int>::iterator i = arr.begin(); i != arr.end(); ++i) {
|
||||
std::cout << *i << std::endl;
|
||||
}
|
||||
|
||||
// C++11 写法
|
||||
// & 启用了引用, 如果没有则对 arr 中的元素只能读取不能修改
|
||||
for(auto &i : arr) {
|
||||
std::cout << i << std::endl;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
34
code/2/2.5.cpp
Normal file
34
code/2/2.5.cpp
Normal file
@@ -0,0 +1,34 @@
|
||||
//
|
||||
// 2.5.cpp
|
||||
// c++1x tutorial
|
||||
//
|
||||
// created by changkun at shiyanlou.com
|
||||
//
|
||||
// 初始化列表
|
||||
|
||||
|
||||
#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});
|
||||
}
|
||||
76
code/2/2.6.cpp
Normal file
76
code/2/2.6.cpp
Normal file
@@ -0,0 +1,76 @@
|
||||
//
|
||||
// 2.6.cpp
|
||||
// c++1x tutorial
|
||||
//
|
||||
// created by changkun at shiyanlou.com
|
||||
//
|
||||
// 模板增强
|
||||
|
||||
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
template class std::vector<bool>; // 强行实例化
|
||||
extern template class std::vector<double>; // 不在该编译文件中实例化模板
|
||||
|
||||
|
||||
template< typename T, typename U, int value>
|
||||
class SuckType {
|
||||
public:
|
||||
T a;
|
||||
U b;
|
||||
SuckType():a(value),b(value){}
|
||||
};
|
||||
// template< typename T>
|
||||
// typedef SuckType<std::vector<int>, T, 1> NewType; // 不合法
|
||||
|
||||
template <typename T>
|
||||
using NewType = SuckType<int, T, 1>; // 合法
|
||||
|
||||
// 默认模板类型
|
||||
template<typename T = int, typename U = int>
|
||||
auto add(T x, U y) -> decltype(x+y) {
|
||||
return x+y;
|
||||
}
|
||||
|
||||
// sizeof...
|
||||
template<typename... Args>
|
||||
void magic(Args... args) {
|
||||
std::cout << sizeof...(args) << std::endl;
|
||||
}
|
||||
|
||||
|
||||
// 1. 递归解参数包
|
||||
template<typename T>
|
||||
void printf1(T value) {
|
||||
std::cout << value << std::endl;
|
||||
}
|
||||
template<typename T, typename... Args>
|
||||
void printf1(T value, Args... args) {
|
||||
std::cout << value << std::endl;
|
||||
printf1(args...);
|
||||
}
|
||||
// 2.初始化列表展开解参数包
|
||||
template<typename T, typename... Args>
|
||||
auto printf2(T value, Args... args) {
|
||||
std::cout << value << std::endl;
|
||||
return std::initializer_list<T>{([&] {
|
||||
std::cout << args << std::endl;
|
||||
}(), value)...};
|
||||
}
|
||||
|
||||
int main() {
|
||||
|
||||
std::vector<std::vector<int>> wow; // 注意尖括号
|
||||
|
||||
NewType<int> t;
|
||||
|
||||
magic();
|
||||
magic(1);
|
||||
magic(1,"");
|
||||
|
||||
printf1(1, 2.3, "abc");
|
||||
printf2(1, 2.3, "abc");
|
||||
return 0;
|
||||
}
|
||||
65
code/2/2.7.cpp
Normal file
65
code/2/2.7.cpp
Normal file
@@ -0,0 +1,65 @@
|
||||
//
|
||||
// 2.7.cpp
|
||||
// c++1x tutorial
|
||||
//
|
||||
// created by changkun at shiyanlou.com
|
||||
//
|
||||
// 面向对象增强
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
class Base {
|
||||
public:
|
||||
std::string str;
|
||||
int value;
|
||||
Base() = delete;
|
||||
Base(std::string s) {
|
||||
str = s;
|
||||
}
|
||||
|
||||
// 委托构造
|
||||
Base(std::string s, int v) : Base(s) {
|
||||
value = v;
|
||||
}
|
||||
|
||||
// 终止重载
|
||||
virtual void foo() final {
|
||||
return;
|
||||
}
|
||||
virtual void foo(int v) {
|
||||
value = v;
|
||||
}
|
||||
};
|
||||
class Subclass final : public Base {
|
||||
public:
|
||||
double floating;
|
||||
Subclass() = delete;
|
||||
|
||||
// 继承构造
|
||||
Subclass(double f, int v, std::string s) : Base(s, v) {
|
||||
floating = f;
|
||||
}
|
||||
|
||||
// 显式重载
|
||||
virtual void foo(int v) override {
|
||||
std::cout << v << std::endl;
|
||||
value = v;
|
||||
}
|
||||
}; // 合法 final
|
||||
|
||||
// class Subclass2 : Subclass {
|
||||
// }; // 非法, Subclass 已 final
|
||||
// class Subclass3 : Base {
|
||||
// void foo(); // 非法, foo 已 final
|
||||
// }
|
||||
|
||||
int main() {
|
||||
// Subclass oops; // 非法, 默认构造已删除
|
||||
Subclass s(1.2, 3, "abc");
|
||||
|
||||
s.foo(1);
|
||||
|
||||
std::cout << s.floating << std::endl;
|
||||
std::cout << s.value << std::endl;
|
||||
std::cout << s.str << std::endl;
|
||||
}
|
||||
51
code/2/2.8.cpp
Normal file
51
code/2/2.8.cpp
Normal file
@@ -0,0 +1,51 @@
|
||||
//
|
||||
// 2.8.cpp
|
||||
// c++1x tutorial
|
||||
//
|
||||
// created by changkun at shiyanlou.com
|
||||
//
|
||||
// 强类型枚举
|
||||
|
||||
#include <iostream>
|
||||
template<typename T>
|
||||
std::ostream& operator<<(typename std::enable_if<std::is_enum<T>::value, std::ostream>::type& stream, const T& e)
|
||||
{
|
||||
return stream << static_cast<typename std::underlying_type<T>::type>(e);
|
||||
}
|
||||
|
||||
// 如果两个都定义为 value1 和 value2,将引发重定义错误
|
||||
enum Left {
|
||||
left_value1 = 1,
|
||||
left_value2
|
||||
};
|
||||
enum Right {
|
||||
right_value1 = 1,
|
||||
right_value2
|
||||
};
|
||||
|
||||
enum class new_enum : unsigned int{
|
||||
value1,
|
||||
value2,
|
||||
value3 = 100,
|
||||
value4 = 100
|
||||
};
|
||||
|
||||
int main() {
|
||||
|
||||
if (Left::left_value1 == Right::right_value2) {
|
||||
std::cout << "Left::value1 == Right::value2" << std::endl;
|
||||
}
|
||||
|
||||
// 引发编译错误
|
||||
// if(new_enum::value1 == 1) {
|
||||
// std::cout << "true!" << std::endl;
|
||||
// }
|
||||
if (new_enum::value3 == new_enum::value4) {
|
||||
std::cout << "new_enum::value3 == new_enum::value4" << std::endl;
|
||||
}
|
||||
|
||||
std::cout << new_enum::value3 << std::endl;
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user