From 664613cf1a5343ae011d9af15cbdd38c3b44dd4e Mon Sep 17 00:00:00 2001 From: Light-City <455954986@qq.com> Date: Fri, 10 Jan 2020 11:17:35 +0800 Subject: [PATCH] update --- README.md | 3 +- modern_C++_30/.CMakeLists.txt.un~ | Bin 11723 -> 1445 bytes modern_C++_30/CMakeLists.txt | 4 + modern_C++_30/CMakeLists.txt~ | 64 +++++++++ modern_C++_30/constexpr/a.out | Bin 0 -> 8744 bytes modern_C++_30/constexpr/container.cpp | 43 ++++++ modern_C++_30/constexpr/newconstexpr.cpp | 78 +++++++++++ modern_C++_30/constexpr/output_container.h | 150 +++++++++++++++++++++ modern_C++_30/constexpr/sqrt.cpp | 47 +++++++ modern_C++_30/constexpr/test3.cpp | 31 +++++ 10 files changed, 419 insertions(+), 1 deletion(-) create mode 100644 modern_C++_30/CMakeLists.txt~ create mode 100755 modern_C++_30/constexpr/a.out create mode 100644 modern_C++_30/constexpr/container.cpp create mode 100644 modern_C++_30/constexpr/newconstexpr.cpp create mode 100644 modern_C++_30/constexpr/output_container.h create mode 100644 modern_C++_30/constexpr/sqrt.cpp create mode 100644 modern_C++_30/constexpr/test3.cpp diff --git a/README.md b/README.md index 2c0323e..3b1a993 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ ### 0.项目概要 -学习C++内容,包括理论、源码、实践、课程代码、项目等 +学习C++内容,包括理论、源码、实践、课程代码、项目等。 ### 1.基础部分 @@ -146,6 +146,7 @@ for(decl:col) { - [是不是应该返回对象?](./modern_C++_30/returnObj) - [编译期多态:泛型编程和模板入门](./modern_C++_30/compilerpoly) - [SFINAE:不是错误的替换失败是怎么回事?](./modern_C++_30/SFINAE) +- [constexpr:一个常态的世界](./modern_C++_30/constexpr) ### 4.拓展部分 diff --git a/modern_C++_30/.CMakeLists.txt.un~ b/modern_C++_30/.CMakeLists.txt.un~ index 65349bbf9decb1e9e6cbfd89e514fc2cd0b352f1..49bafb8c9337cace1e6b63f547baa0348d798297 100644 GIT binary patch literal 1445 zcmWH`%$*;a=aT=Ffl2YYG`F03YEb3MrUt1O+#3AQ4kPc9`gk{^&h=YY8&1hi6sY44uaE?QcB2dI>WG1Gh#HUuICYP2ZCgr4R f6c-kiC?x0S6_=z|6cp)$xO&M21)8Rf&sPBesmemO literal 11723 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 Bhxh;h literal 0 HcmV?d00001 diff --git a/modern_C++_30/constexpr/container.cpp b/modern_C++_30/constexpr/container.cpp new file mode 100644 index 0000000..bf2cd74 --- /dev/null +++ b/modern_C++_30/constexpr/container.cpp @@ -0,0 +1,43 @@ +// +// Created by light on 19-12-16. +// + +#include +#include +#include +#include +#include "output_container.h" + + +using namespace std; + +int main() { + map mp{ + {1, 1}, + {2, 4}, + {3, 9}}; + cout << mp << endl; + vector> vv{ + {1, 1}, + {2, 4}, + {3, 9}}; + cout << vv << endl; + + pair p{1, 2}; + cout << p << endl; + + set s{1, 2, 3}; + cout << s << endl; + + vector v{'a', 'b'}; + cout << v << endl; + set vs{"a", "b"}; + cout << vs << endl; + + map mm{ + {1, "23"}, + {2, "234hi"} + }; + cout << mm << endl; + +} diff --git a/modern_C++_30/constexpr/newconstexpr.cpp b/modern_C++_30/constexpr/newconstexpr.cpp new file mode 100644 index 0000000..b8b9570 --- /dev/null +++ b/modern_C++_30/constexpr/newconstexpr.cpp @@ -0,0 +1,78 @@ +// +// Created by light on 20-1-7. +// + +#include +#include +#include + +using namespace std; + +// C++17 内联变量 +struct magic { +// static const int number = 42; // error + static constexpr int number = 42; // ok +// 类的静态constexpr成员变量默认就是内联的。 +// static inline const int number = 42; // ok +// const常量和类外面的constexpr变量是不默认内联,需要手工加inline关键字才会变成内联 +}; + +// 内联变量之前用这个方法,称为one definition rule,有了内联变量及模板,则不受这条规则限制! +// const int magic::number = 42; // ok + + +// C++14 变量模板 +// 之前我们需要用类静态数据成员来表达的东西,使用变量模板可以更简洁地表达。 +namespace my { + template + inline constexpr bool + is_trivially_destructible_v = + std::is_trivially_destructible< + T>::value; +} +// 不重要析构 +class A { +}; + +// 重要析构 +class B { + ~B() {} +}; + +int main() { + std::cout << magic::number << std::endl; + + std::vector v; + v.push_back(magic::number); // undefined reference to `magic::number' + std::cout << v[0] << std::endl; + // 不重要的析构 + std::cout << is_trivially_destructible_v << std::endl; + std::cout << is_trivially_destructible_v << std::endl; + + // constexpr变量仍是const + + constexpr int a = 42; + const int &b = a; + // 上述const不能去掉,否则报如下错误: + // binding reference of type ‘int&’ to ‘const int’ discards qualifiers + + + // constexpr 构造函数和字面类型 + // C++14 放开了 constexpr函数里的循环 + // C++20 放开了 try...catch语句 和 asm声明 + // constexpr函数里不能使用goto语句 + + // 一个有意思的情况是一个类的构造函数。如果一个类的构造函数里面只包含常量表达式、 + // 满足对 constexpr 函数的限制的话(这也意味着,里面不可以有任何动态内存分配), + // 并且类的析构函数是平凡的,那这个类就可以被称为是一个字面类型。 + std::array ay; + + + constexpr string_view sv{"hi"}; + constexpr pair pr{sv[0], sv[1]}; + constexpr array aa{pr.first, pr.second}; + constexpr int n1 = aa[0]; + constexpr int n2 = aa[1]; + cout << n1 << ' ' << n2 << '\n'; + +} \ No newline at end of file diff --git a/modern_C++_30/constexpr/output_container.h b/modern_C++_30/constexpr/output_container.h new file mode 100644 index 0000000..f7f038f --- /dev/null +++ b/modern_C++_30/constexpr/output_container.h @@ -0,0 +1,150 @@ +// +// Created by light on 20-1-8. +// + +#ifndef MORDEN_C_OUTPUT_CONTAINER_H +#define MORDEN_C_OUTPUT_CONTAINER_H + +#include // std::ostream +#include // std::false_type/true_type/decay_t/is_same_v +#include // std::declval/pair + +// 检测是否是pair +template +struct is_pair : std::false_type { +}; +template +struct is_pair> : std::true_type { +}; +template +inline constexpr bool is_pair_v = is_pair::value; + +// 检测是否可以直接输出 +template +struct has_output_function { + template + static auto output(U *ptr) + -> decltype(std::declval() << *ptr, + std::true_type()); + + template + static std::false_type output(...); + + static constexpr bool value = + decltype(output(nullptr))::value; +}; + +template +inline constexpr bool has_output_function_v = + has_output_function::value; + + +enum CHARS { + ORD, // 其他类型 + CHAR, // char 类型 + STRING // string 类型 +}; + +template +int ischarOrString(T &elem) { + using std::decay_t; + using std::is_same_v; + using element_type = decay_t; + constexpr bool is_char_v = is_same_v; + constexpr bool is_string_v = is_same_v || + is_same_v || + is_same_v; + if (is_char_v) + return CHAR; + else if (is_string_v) + return STRING; + else + return ORD; +} + +template +void output(T &elem, int type, std::ostream &os) { + switch (type) { + case CHAR: + os << '\'' << elem << '\''; + break; + case STRING: + os << '\"' << elem << '\"'; + break; + case ORD: + os << elem; + break; + } +} + +template +auto output_element(std::ostream &os, const T &element, + const Cont &) +-> typename std::enable_if::value, bool>::type { + int ftype = ischarOrString(element.first); + int stype = ischarOrString(element.second); + + output(element.first, ftype, os); + os << " => "; + output(element.second, stype, os); + return true; +} + +template +auto output_element(std::ostream &os, const T &element, + const Cont &) +-> typename std::enable_if::value, bool>::type { + int etype = ischarOrString(element); + output(element, etype, os); + return false; +} + +template +std::ostream &operator<<(std::ostream &os, const std::pair &pr) { + os << '(' << pr.first << ", " << pr.second << ')'; + return os; +} + +//template +//auto output_element(std::ostream& os, const T& element, +// const Cont&, const std::true_type) +//-> decltype(std::declval(), os) +//{ +// os << element.first << " => " << element.second; +// return os; +//} +// +//template +//auto output_element(std::ostream& os, const T& element, +// const Cont&, ...) +//-> decltype(os) +//{ +// os << element; +// return os; +//} + + + +// 针对没有输出函数的容器处理 +template>> +auto operator<<(std::ostream &os, const T &container) +-> decltype(container.begin(), container.end(), os) { + os << "{ "; + if (!container.empty()) { + bool on_first_element = true; + for (auto elem:container) { + if (!on_first_element) { + os << ", "; + } else { + on_first_element = false; + } + output_element(os, elem, container); + } + } + os << " }"; + return os; +} + + +#endif //MORDEN_C_OUTPUT_CONTAINER_H diff --git a/modern_C++_30/constexpr/sqrt.cpp b/modern_C++_30/constexpr/sqrt.cpp new file mode 100644 index 0000000..6a12987 --- /dev/null +++ b/modern_C++_30/constexpr/sqrt.cpp @@ -0,0 +1,47 @@ +// +// Created by light on 20-1-7. +// + +#include +#include + +int sqr(int n) { + return n * n; +} + +int rand() { + return std::rand(); +} + +// constant expression +constexpr int sqr1(int n) { + return n * n; +} + +constexpr int factorial(int n) { + // n是普通的int 不能使用static_assert +// static_assert(n>=0); //error + // 正确方式 + if (n < 0) { + throw std::invalid_argument( + "Arg must be non-negative"); + } + + if (n == 0) { + return 1; + } else { + return n * factorial(n - 1); + } +} + +int main() { + int a[sqr(3)]; // ok + const int n1 = sqr(3); // ok + + constexpr int n = sqr1(3); // constexpr=constant expression 常量表达式 + std::array aa; // ok + + std::array b; // ok + int cc[rand()]; + return 0; +} \ No newline at end of file diff --git a/modern_C++_30/constexpr/test3.cpp b/modern_C++_30/constexpr/test3.cpp new file mode 100644 index 0000000..73e8924 --- /dev/null +++ b/modern_C++_30/constexpr/test3.cpp @@ -0,0 +1,31 @@ +// +// Created by light on 20-1-10. +// + +#include + +class test3 { +public: + + int value; + + // constexpr const method - can't chanage the values of object fields and can be evaluated at compile time. + constexpr int getvalue() const { + return (value); + } + + constexpr test3(int Value) + : value(Value) { + } +}; + + +int main() { + + // 加不加都行 + constexpr test3 x(100); // OK. Constructor is constexpr. + + int array[x.getvalue()]; // OK. x.getvalue() is constexpr and can be evaluated at compile time. +} + +