@@ -559,14 +559,14 @@ extern template class std::vector<MagicClass>; // 不在该编译文件中实例
559559在传统 C++ 的编译器中,`>>`一律被当做右移运算符来进行处理。但实际上我们很容易就写出了嵌套模板的代码:
560560
561561```cpp
562- std::vector<std::vector<int>> mtx;
562+ std::vector<std::vector<int>> mtx;
563563```
564564
565565这在传统C++编译器下是不能够被编译的,而 C++11 开始,连续的右尖括号将变得合法,并且能够顺利通过编译。甚至于下下面这种写法都能够通过编译:
566566
567567``` cpp
568568template <bool T> SuckType;
569- std::vector<SuckType<(1 >2 )>> v; // 合法, 但不建议写出这样的代码
569+ std::vector<SuckType<(1 >2 )>> v; // 合法, 但不建议写出这样的代码
570570```
571571
572572### 类型别名模板
@@ -599,7 +599,7 @@ using NewType = SuckType<std::vector, std::string>;
599599```cpp
600600template<typename T, typename U>
601601auto add(T x, U y) -> decltype(x+y) {
602- return x+y
602+ return x+y
603603}
604604```
605605
@@ -610,7 +610,7 @@ return x+y
610610``` cpp
611611template <typename T = int , typename U = int >
612612auto add (T x, U y) -> decltype(x+y) {
613- return x+y
613+ return x+y
614614}
615615```
616616
@@ -626,9 +626,9 @@ template<typename... Ts> class Magic;
626626
627627``` cpp
628628class Magic <int,
629- std::vector<int >,
630- std::map<std::string,
631- std::vector<int >>> darkMagic;
629+ std::vector<int >,
630+ std::map<std::string,
631+ std::vector<int >>> darkMagic;
632632```
633633
634634既然是任意形式,所以个数为0的模板参数也是可以的:`class Magic<> nothing;`。
@@ -652,7 +652,7 @@ template<typename... Args> void printf(const std::string &str, Args... args);
652652```cpp
653653template<typename... Args>
654654void magic(Args... args) {
655- std::cout << sizeof...(args) << std::endl;
655+ std::cout << sizeof...(args) << std::endl;
656656}
657657```
658658我们可以传递任意个参数给 ` magic ` 函数:
@@ -710,14 +710,14 @@ void printf(T0 t0, T... t) {
710710// 编译这个代码需要开启 -std=c++14
711711template<typename T, typename... Args>
712712auto print(T value, Args... args) {
713- std::cout << value << std::endl;
714- return std::initializer_list<T>{([&] {
715- std::cout << args << std::endl;
716- }(), value)...};
713+ std::cout << value << std::endl;
714+ return std::initializer_list<T>{([&] {
715+ std::cout << args << std::endl;
716+ }(), value)...};
717717}
718718int main() {
719- print(1, 2.1, "123");
720- return 0;
719+ print(1, 2.1, "123");
720+ return 0;
721721}
722722```
723723
@@ -753,20 +753,20 @@ C++11 引入了委托构造的概念,这使得构造函数可以在同一个
753753```cpp
754754class Base {
755755public:
756- int value1;
757- int value2;
758- Base() {
759- value1 = 1;
760- }
761- Base(int value) : Base() { // 委托 Base() 构造函数
762- value2 = 2;
763- }
756+ int value1;
757+ int value2;
758+ Base() {
759+ value1 = 1;
760+ }
761+ Base(int value) : Base() { // 委托 Base() 构造函数
762+ value2 = 2;
763+ }
764764};
765765
766766int main() {
767- Base b(2);
768- std::cout << b.value1 << std::endl;
769- std::cout << b.value2 << std::endl;
767+ Base b(2);
768+ std::cout << b.value1 << std::endl;
769+ std::cout << b.value2 << std::endl;
770770}
771771```
772772
@@ -777,23 +777,23 @@ std::cout << b.value2 << std::endl;
777777``` cpp
778778class Base {
779779public:
780- int value1;
781- int value2;
782- Base() {
783- value1 = 1;
784- }
785- Base(int value) : Base() { // 委托 Base() 构造函数
786- value2 = 2;
787- }
780+ int value1;
781+ int value2;
782+ Base() {
783+ value1 = 1;
784+ }
785+ Base(int value) : Base() { // 委托 Base() 构造函数
786+ value2 = 2;
787+ }
788788};
789789class Subclass : public Base {
790790public:
791- using Base::Base; // 继承构造
791+ using Base::Base; // 继承构造
792792};
793793int main() {
794- Subclass s(3);
795- std::cout << s.value1 << std::endl;
796- std::cout << s.value2 << std::endl;
794+ Subclass s(3);
795+ std::cout << s.value1 << std::endl;
796+ std::cout << s.value2 << std::endl;
797797}
798798```
799799
@@ -803,10 +803,10 @@ std::cout << s.value2 << std::endl;
803803
804804```cpp
805805struct Base {
806- virtual void foo();
807- };
808- struct SubClass: Base {
809- void foo();
806+ virtual void foo();
807+ };
808+ struct SubClass: Base {
809+ void foo();
810810};
811811```
812812
@@ -859,10 +859,10 @@ C++11 提供了上述需求的解决方案,允许显式的声明采用或拒
859859
860860``` cpp
861861class Magic {
862- public:
863- Magic() = default; // 显式声明使用编译器生成的构造
864- Magic& operator=(const Magic&) = delete; // 显式声明拒绝编译器生成构造
865- Magic(int magic_number);
862+ public:
863+ Magic() = default; // 显式声明使用编译器生成的构造
864+ Magic& operator=(const Magic&) = delete; // 显式声明拒绝编译器生成构造
865+ Magic(int magic_number);
866866}
867867```
868868
@@ -874,19 +874,19 @@ C++11 引入了枚举类(enumaration class),并使用 `enum class` 的语
874874
875875```cpp
876876enum class new_enum : unsigned int {
877- value1,
878- value2,
879- value3 = 100,
880- value4 = 100
877+ value1,
878+ value2,
879+ value3 = 100,
880+ value4 = 100
881881};
882882```
883883
884884这样定义的枚举实现了类型安全,首先他不能够被隐式的转换为整数,同时也不能够将其与整数数字进行比较,更不可能对不同的枚举类型的枚举值进行比较。但相同枚举值之间如果指定的值相同,那么可以进行比较:
885885
886886``` cpp
887887if (new_enum::value3 == new_enum::value4) {
888- // 会输出
889- std::cout << "new_enum::value3 == new_enum::value4" << std::endl;
888+ // 会输出
889+ std::cout << "new_enum::value3 == new_enum::value4" << std::endl;
890890}
891891```
892892
@@ -899,7 +899,7 @@ std::cout << "new_enum::value3 == new_enum::value4" << std::endl;
899899template <typename T>
900900std::ostream& operator <<(typename std::enable_if<std::is_enum<T>::value, std::ostream>::type& stream, const T& e)
901901{
902- return stream << static_cast<typename std::underlying_type<T >::type>(e);
902+ return stream << static_cast<typename std::underlying_type<T>::type>(e);
903903}
904904```
905905
0 commit comments