|  | @@ -105,7 +105,7 @@ Template Class定义:
 | 
	
		
			
				|  |  |  ```C++
 | 
	
		
			
				|  |  |  template <typename T> class ClassA
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  | -	T member;
 | 
	
		
			
				|  |  | +    T member;
 | 
	
		
			
				|  |  |  };
 | 
	
		
			
				|  |  |  ```
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -124,7 +124,7 @@ void foo(int a);
 | 
	
		
			
				|  |  |  ``` C++
 | 
	
		
			
				|  |  |  // 注意:这并不是有效的C++语法,只是为了说明模板的作用
 | 
	
		
			
				|  |  |  typedef class {
 | 
	
		
			
				|  |  | -	int member;
 | 
	
		
			
				|  |  | +    int member;
 | 
	
		
			
				|  |  |  } ClassA<int>;
 | 
	
		
			
				|  |  |  ```
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -139,11 +139,11 @@ template <typename T>
 | 
	
		
			
				|  |  |  class vector
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  |  public:
 | 
	
		
			
				|  |  | -	void push_back(T const&);
 | 
	
		
			
				|  |  | -	void clear();				
 | 
	
		
			
				|  |  | +    void push_back(T const&);
 | 
	
		
			
				|  |  | +    void clear();				
 | 
	
		
			
				|  |  |  	
 | 
	
		
			
				|  |  |  private:
 | 
	
		
			
				|  |  | -	T* elements;
 | 
	
		
			
				|  |  | +    T* elements;
 | 
	
		
			
				|  |  |  };
 | 
	
		
			
				|  |  |  ```
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -225,7 +225,7 @@ private:
 | 
	
		
			
				|  |  |  template <typename T>
 | 
	
		
			
				|  |  |  void vector<T>::clear()  // 函数的实现放在这里
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  | -	// Function body
 | 
	
		
			
				|  |  | +    // Function body
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  ```
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -668,11 +668,11 @@ Float  : VInt64Mul(floatx2, floatx2)
 | 
	
		
			
				|  |  |  for(v4a, v4b : vectorsA, vectorsB)
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  |      if type is Int8, Int16
 | 
	
		
			
				|  |  | -		VInt32Mul( ConvertToInt32(v4a), ConvertToInt32(v4b) )
 | 
	
		
			
				|  |  | -	elif type is Int32
 | 
	
		
			
				|  |  | -		VInt32Mul( v4a, v4b )
 | 
	
		
			
				|  |  | -	elif type is Float
 | 
	
		
			
				|  |  | -		...
 | 
	
		
			
				|  |  | +        VInt32Mul( ConvertToInt32(v4a), ConvertToInt32(v4b) )
 | 
	
		
			
				|  |  | +    elif type is Int32
 | 
	
		
			
				|  |  | +        VInt32Mul( v4a, v4b )
 | 
	
		
			
				|  |  | +    elif type is Float
 | 
	
		
			
				|  |  | +        ...
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  ```
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -1175,7 +1175,7 @@ template <typename T> // 嗯,需要一个T
 | 
	
		
			
				|  |  |  class TypeToID<T*> // 我要对所有的指针类型特化,所以这里就写T*
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  |  public:
 | 
	
		
			
				|  |  | - static int const ID = 0x80000000;	// 用最高位表示它是一个指针
 | 
	
		
			
				|  |  | +    static int const ID = 0x80000000;	// 用最高位表示它是一个指针
 | 
	
		
			
				|  |  |  };
 | 
	
		
			
				|  |  |  ```
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -1205,7 +1205,7 @@ public:
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  void PrintID()
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  | -	cout << "ID of float*: " << TypeToID< TypeToID<float*>::SameAsT >::ID << endl;
 | 
	
		
			
				|  |  | +    cout << "ID of float*: " << TypeToID< TypeToID<float*>::SameAsT >::ID << endl;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  ```
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -1461,7 +1461,7 @@ void foo(){
 | 
	
		
			
				|  |  |  // ----------- X.h ------------
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  template <typename T> struct X {
 | 
	
		
			
				|  |  | -      // 实现代码
 | 
	
		
			
				|  |  | +    // 实现代码
 | 
	
		
			
				|  |  |  };
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  // ---------- X.cpp -----------
 | 
	
	
		
			
				|  | @@ -2123,7 +2123,7 @@ void foo(){
 | 
	
		
			
				|  |  |  ``` C++
 | 
	
		
			
				|  |  |  template <typename T, typename U>
 | 
	
		
			
				|  |  |  void foo(T t, typename U::type u) {
 | 
	
		
			
				|  |  | -  // ...
 | 
	
		
			
				|  |  | +    // ...
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  ```
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -2131,16 +2131,16 @@ void foo(T t, typename U::type u) {
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  ``` C++
 | 
	
		
			
				|  |  |  struct X {
 | 
	
		
			
				|  |  | -  typedef float type;
 | 
	
		
			
				|  |  | +    typedef float type;
 | 
	
		
			
				|  |  |  };
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  template <typename T, typename U>
 | 
	
		
			
				|  |  |  void foo(T t, typename U::type u) {
 | 
	
		
			
				|  |  | -  // ...
 | 
	
		
			
				|  |  | +    // ...
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  void callFoo() {
 | 
	
		
			
				|  |  | -  foo<int, X>(5, 5.0); // T == int, typename U::type == X::type == float
 | 
	
		
			
				|  |  | +    foo<int, X>(5, 5.0); // T == int, typename U::type == X::type == float
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  ```
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -2148,11 +2148,11 @@ void callFoo() {
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  ```C++
 | 
	
		
			
				|  |  |  struct X {
 | 
	
		
			
				|  |  | -  typedef float type;
 | 
	
		
			
				|  |  | +    typedef float type;
 | 
	
		
			
				|  |  |  };
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  struct Y {
 | 
	
		
			
				|  |  | -  typedef float type2;
 | 
	
		
			
				|  |  | +    typedef float type2;
 | 
	
		
			
				|  |  |  };
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  template <typename T, typename U>
 | 
	
	
		
			
				|  | @@ -2161,8 +2161,8 @@ void foo(T t, typename U::type u) {
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  void callFoo() {
 | 
	
		
			
				|  |  | -  foo<int, X>(5, 5.0); // T == int, typename U::type == X::type == float
 | 
	
		
			
				|  |  | -  foo<int, Y>(5, 5.0); // ???
 | 
	
		
			
				|  |  | +    foo<int, X>(5, 5.0); // T == int, typename U::type == X::type == float
 | 
	
		
			
				|  |  | +    foo<int, Y>(5, 5.0); // ???
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  ```
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -2182,16 +2182,16 @@ error: no matching function for call to 'foo'
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  ```C++
 | 
	
		
			
				|  |  |  struct X {
 | 
	
		
			
				|  |  | -  typedef float type;
 | 
	
		
			
				|  |  | +    typedef float type;
 | 
	
		
			
				|  |  |  };
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  struct Y {
 | 
	
		
			
				|  |  | -  typedef float type2;
 | 
	
		
			
				|  |  | +    typedef float type2;
 | 
	
		
			
				|  |  |  };
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  template <typename T, typename U>
 | 
	
		
			
				|  |  |  void foo(T t, typename U::type u) {
 | 
	
		
			
				|  |  | -  // ...
 | 
	
		
			
				|  |  | +    // ...
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  template <typename T, typename U>
 | 
	
	
		
			
				|  | @@ -2199,8 +2199,8 @@ void foo(T t, typename U::type2 u) {
 | 
	
		
			
				|  |  |    // ...
 | 
	
		
			
				|  |  |  } 
 | 
	
		
			
				|  |  |  void callFoo() {
 | 
	
		
			
				|  |  | -  foo<int, X>(5, 5.0); // T == int, typename U::type == X::type == float
 | 
	
		
			
				|  |  | -  foo<int, Y>( 1, 1.0 ); // ???
 | 
	
		
			
				|  |  | +    foo<int, X>(5, 5.0); // T == int, typename U::type == X::type == float
 | 
	
		
			
				|  |  | +    foo<int, Y>( 1, 1.0 ); // ???
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  ```
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -2245,9 +2245,9 @@ void foo(A const&) {}
 | 
	
		
			
				|  |  |  void foo(B const&) {}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  void callFoo() {
 | 
	
		
			
				|  |  | -  foo( A() );
 | 
	
		
			
				|  |  | -  foo( B() );
 | 
	
		
			
				|  |  | -  foo( C() );
 | 
	
		
			
				|  |  | +    foo( A() );
 | 
	
		
			
				|  |  | +    foo( B() );
 | 
	
		
			
				|  |  | +    foo( C() );
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  ```
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -2271,17 +2271,17 @@ void callFoo() {
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  ```C++
 | 
	
		
			
				|  |  |  template <
 | 
	
		
			
				|  |  | -  typename T0, 
 | 
	
		
			
				|  |  | -  // 一大坨其他模板参数
 | 
	
		
			
				|  |  | -  typename U = /* 和前面T有关的一大坨 */
 | 
	
		
			
				|  |  | +    typename T0, 
 | 
	
		
			
				|  |  | +    // 一大坨其他模板参数
 | 
	
		
			
				|  |  | +    typename U = /* 和前面T有关的一大坨 */
 | 
	
		
			
				|  |  |  >
 | 
	
		
			
				|  |  |  RType /* 和模板参数有关的一大坨 */
 | 
	
		
			
				|  |  |  functionName (
 | 
	
		
			
				|  |  | -   PType0 /* PType0 是和模板参数有关的一大坨 */,
 | 
	
		
			
				|  |  | -   PType1 /* PType1 是和模板参数有关的一大坨 */,
 | 
	
		
			
				|  |  | -   // ... 其他参数
 | 
	
		
			
				|  |  | +    PType0 /* PType0 是和模板参数有关的一大坨 */,
 | 
	
		
			
				|  |  | +    PType1 /* PType1 是和模板参数有关的一大坨 */,
 | 
	
		
			
				|  |  | +    // ... 其他参数
 | 
	
		
			
				|  |  |  ) {
 | 
	
		
			
				|  |  | -  // 实现,和模板参数有关的一大坨
 | 
	
		
			
				|  |  | +    // 实现,和模板参数有关的一大坨
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  ```
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -2289,19 +2289,19 @@ functionName (
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  ```C++
 | 
	
		
			
				|  |  |  template <
 | 
	
		
			
				|  |  | -  typename T, 
 | 
	
		
			
				|  |  | -  typename U = typename vector<T>::iterator // 1
 | 
	
		
			
				|  |  | +    typename T, 
 | 
	
		
			
				|  |  | +    typename U = typename vector<T>::iterator // 1
 | 
	
		
			
				|  |  |  >
 | 
	
		
			
				|  |  |  typename vector<T>::value_type  // 1
 | 
	
		
			
				|  |  | -  foo( 
 | 
	
		
			
				|  |  | -      T*, // 1
 | 
	
		
			
				|  |  | -      T&, // 1
 | 
	
		
			
				|  |  | -      typename T::internal_type, // 1
 | 
	
		
			
				|  |  | -      typename add_reference<T>::type, // 1
 | 
	
		
			
				|  |  | -      int // 这里都不需要 substitution
 | 
	
		
			
				|  |  | -  )
 | 
	
		
			
				|  |  | +foo(
 | 
	
		
			
				|  |  | +    T*, // 1
 | 
	
		
			
				|  |  | +    T&, // 1
 | 
	
		
			
				|  |  | +    typename T::internal_type, // 1
 | 
	
		
			
				|  |  | +    typename add_reference<T>::type, // 1
 | 
	
		
			
				|  |  | +    int // 这里都不需要 substitution
 | 
	
		
			
				|  |  | +)
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  | -   // 整个实现部分,都没有 substitution。这个很关键。
 | 
	
		
			
				|  |  | +  // 整个实现部分,都没有 substitution。这个很关键。
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  ```
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -2311,11 +2311,11 @@ typename vector<T>::value_type  // 1
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  ```C++
 | 
	
		
			
				|  |  |  struct X {
 | 
	
		
			
				|  |  | -  typedef int type;
 | 
	
		
			
				|  |  | +    typedef int type;
 | 
	
		
			
				|  |  |  };
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  struct Y {
 | 
	
		
			
				|  |  | -  typedef int type2;
 | 
	
		
			
				|  |  | +    typedef int type2;
 | 
	
		
			
				|  |  |  };
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  template <typename T> void foo(typename T::type);    // Foo0
 | 
	
	
		
			
				|  | @@ -2323,9 +2323,9 @@ template <typename T> void foo(typename T::type2);   // Foo1
 | 
	
		
			
				|  |  |  template <typename T> void foo(T);                   // Foo2
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  void callFoo() {
 | 
	
		
			
				|  |  | -   foo<X>(5);    // Foo0: Succeed, Foo1: Failed,  Foo2: Failed
 | 
	
		
			
				|  |  | -   foo<Y>(10);   // Foo0: Failed,  Foo1: Succeed, Foo2: Failed
 | 
	
		
			
				|  |  | -   foo<int>(15); // Foo0: Failed,  Foo1: Failed,  Foo2: Succeed
 | 
	
		
			
				|  |  | +    foo<X>(5);    // Foo0: Succeed, Foo1: Failed,  Foo2: Failed
 | 
	
		
			
				|  |  | +    foo<Y>(10);   // Foo0: Failed,  Foo1: Succeed, Foo2: Failed
 | 
	
		
			
				|  |  | +    foo<int>(15); // Foo0: Failed,  Foo1: Failed,  Foo2: Succeed
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  ```
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -2337,33 +2337,33 @@ std/boost库中的 `enable_if` 是 SFINAE 最直接也是最主要的应用。
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  ```C++
 | 
	
		
			
				|  |  |  struct ICounter {
 | 
	
		
			
				|  |  | -  virtual void increase() = 0;
 | 
	
		
			
				|  |  | -  virtual ~ICounter() {}
 | 
	
		
			
				|  |  | +    virtual void increase() = 0;
 | 
	
		
			
				|  |  | +    virtual ~ICounter() {}
 | 
	
		
			
				|  |  |  };
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  struct Counter: public ICounter {
 | 
	
		
			
				|  |  | -   void increase() override {
 | 
	
		
			
				|  |  | -      // Implements
 | 
	
		
			
				|  |  | -   }
 | 
	
		
			
				|  |  | +    void increase() override {
 | 
	
		
			
				|  |  | +        // Implements
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  |  };
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  template <typename T>
 | 
	
		
			
				|  |  |  void inc_counter(T& counterObj) {
 | 
	
		
			
				|  |  | -  counterObj.increase();
 | 
	
		
			
				|  |  | +    counterObj.increase();
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  template <typename T>
 | 
	
		
			
				|  |  |  void inc_counter(T& intTypeCounter){
 | 
	
		
			
				|  |  | -  ++intTypeCounter;
 | 
	
		
			
				|  |  | +    ++intTypeCounter;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  void doSomething() {
 | 
	
		
			
				|  |  | -  Counter cntObj;
 | 
	
		
			
				|  |  | -  uint32_t cntUI32;
 | 
	
		
			
				|  |  | +    Counter cntObj;
 | 
	
		
			
				|  |  | +    uint32_t cntUI32;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -  // blah blah blah
 | 
	
		
			
				|  |  | -  inc_counter(cntObj);
 | 
	
		
			
				|  |  | -  inc_counter(cntUI32);
 | 
	
		
			
				|  |  | +    // blah blah blah
 | 
	
		
			
				|  |  | +    inc_counter(cntObj);
 | 
	
		
			
				|  |  | +    inc_counter(cntUI32);
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  ```
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -2382,16 +2382,16 @@ template <typename T> void inc_counter(T& intTypeCounter);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  ```C++
 | 
	
		
			
				|  |  |  template <typename T> void inc_counter(
 | 
	
		
			
				|  |  | -  T& counterObj, 
 | 
	
		
			
				|  |  | -  typename std::enable_if<
 | 
	
		
			
				|  |  | -    std::is_base_of<ICounter, T>::value
 | 
	
		
			
				|  |  | -  >::type* = nullptr );
 | 
	
		
			
				|  |  | +    T& counterObj, 
 | 
	
		
			
				|  |  | +    typename std::enable_if<
 | 
	
		
			
				|  |  | +        std::is_base_of<ICounter, T>::value
 | 
	
		
			
				|  |  | +    >::type* = nullptr );
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  template <typename T> void inc_counter(
 | 
	
		
			
				|  |  | -  T& counterInt,
 | 
	
		
			
				|  |  | -  typename std::enable_if<
 | 
	
		
			
				|  |  | -    std::is_integral<T>::value
 | 
	
		
			
				|  |  | -  >::type* = nullptr );
 | 
	
		
			
				|  |  | +    T& counterInt,
 | 
	
		
			
				|  |  | +    typename std::enable_if<
 | 
	
		
			
				|  |  | +        std::is_integral<T>::value
 | 
	
		
			
				|  |  | +    >::type* = nullptr );
 | 
	
		
			
				|  |  |  ```
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  然后我们解释一下,这个 `enable_if` 是怎么工作的,语法为什么这么丑:
 | 
	
	
		
			
				|  | @@ -2426,9 +2426,9 @@ void inc_counter(ICounter& counterObj);
 | 
	
		
			
				|  |  |  ```C++
 | 
	
		
			
				|  |  |  struct ICounter {};
 | 
	
		
			
				|  |  |  struct Counter: public ICounter {
 | 
	
		
			
				|  |  | -  void increase() {
 | 
	
		
			
				|  |  | -    // impl
 | 
	
		
			
				|  |  | -  }
 | 
	
		
			
				|  |  | +    void increase() {
 | 
	
		
			
				|  |  | +        // impl
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  |  };
 | 
	
		
			
				|  |  |  ```
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -2442,13 +2442,13 @@ template <typename T>
 | 
	
		
			
				|  |  |  void inc_counter(T& c) { ++c; };
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  void doSomething() {
 | 
	
		
			
				|  |  | -  Counter cntObj;
 | 
	
		
			
				|  |  | -  uint32_t cntUI32;
 | 
	
		
			
				|  |  | +    Counter cntObj;
 | 
	
		
			
				|  |  | +    uint32_t cntUI32;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -  // blah blah blah
 | 
	
		
			
				|  |  | -  inc_counter(cntObj); // 1
 | 
	
		
			
				|  |  | -  inc_counter(static_cast<ICounter&>(cntObj)); // 2
 | 
	
		
			
				|  |  | -  inc_counter(cntUI32); // 3
 | 
	
		
			
				|  |  | +    // blah blah blah
 | 
	
		
			
				|  |  | +    inc_counter(cntObj); // 1
 | 
	
		
			
				|  |  | +    inc_counter(static_cast<ICounter&>(cntObj)); // 2
 | 
	
		
			
				|  |  | +    inc_counter(cntUI32); // 3
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  ```
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -2466,34 +2466,34 @@ void doSomething() {
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  struct ICounter {};
 | 
	
		
			
				|  |  |  struct Counter: public ICounter {
 | 
	
		
			
				|  |  | -  void increase() {
 | 
	
		
			
				|  |  | -    // impl
 | 
	
		
			
				|  |  | -  }
 | 
	
		
			
				|  |  | +    void increase() {
 | 
	
		
			
				|  |  | +        // impl
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  |  };
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  template <typename T> void inc_counter(
 | 
	
		
			
				|  |  | -  T& counterObj, 
 | 
	
		
			
				|  |  | -  typename std::enable_if<
 | 
	
		
			
				|  |  | -    std::is_base_of<ICounter, T>::value
 | 
	
		
			
				|  |  | -  >::type* = nullptr ){
 | 
	
		
			
				|  |  | -  counterObj.increase();  
 | 
	
		
			
				|  |  | +    T& counterObj, 
 | 
	
		
			
				|  |  | +    typename std::enable_if<
 | 
	
		
			
				|  |  | +        std::is_base_of<ICounter, T>::value
 | 
	
		
			
				|  |  | +    >::type* = nullptr ){
 | 
	
		
			
				|  |  | +    counterObj.increase();  
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  template <typename T> void inc_counter(
 | 
	
		
			
				|  |  | -  T& counterInt,
 | 
	
		
			
				|  |  | -  typename std::enable_if<
 | 
	
		
			
				|  |  | -    std::is_integral<T>::value
 | 
	
		
			
				|  |  | -  >::type* = nullptr ){
 | 
	
		
			
				|  |  | -  ++counterInt;
 | 
	
		
			
				|  |  | +    T& counterInt,
 | 
	
		
			
				|  |  | +    typename std::enable_if<
 | 
	
		
			
				|  |  | +        std::is_integral<T>::value
 | 
	
		
			
				|  |  | +    >::type* = nullptr ){
 | 
	
		
			
				|  |  | +    ++counterInt;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |    
 | 
	
		
			
				|  |  |  void doSomething() {
 | 
	
		
			
				|  |  | -  Counter cntObj;
 | 
	
		
			
				|  |  | -  uint32_t cntUI32;
 | 
	
		
			
				|  |  | +    Counter cntObj;
 | 
	
		
			
				|  |  | +    uint32_t cntUI32;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -  // blah blah blah
 | 
	
		
			
				|  |  | -  inc_counter(cntObj); // OK!
 | 
	
		
			
				|  |  | -  inc_counter(cntUI32); // OK!
 | 
	
		
			
				|  |  | +    // blah blah blah
 | 
	
		
			
				|  |  | +    inc_counter(cntObj); // OK!
 | 
	
		
			
				|  |  | +    inc_counter(cntUI32); // OK!
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  ```
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -2513,28 +2513,28 @@ template <typename T> void foo(T& c, decltype(c.increase())* = nullptr);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  ```C++
 | 
	
		
			
				|  |  |  struct Counter {
 | 
	
		
			
				|  |  | -   void increase() {
 | 
	
		
			
				|  |  | -      // Implements
 | 
	
		
			
				|  |  | -   }
 | 
	
		
			
				|  |  | +    void increase() {
 | 
	
		
			
				|  |  | +        // Implements
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  |  };
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  template <typename T>
 | 
	
		
			
				|  |  |  void inc_counter(T& intTypeCounter, std::decay_t<decltype(++intTypeCounter)>* = nullptr) {
 | 
	
		
			
				|  |  | -  ++intTypeCounter;
 | 
	
		
			
				|  |  | +    ++intTypeCounter;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  template <typename T>
 | 
	
		
			
				|  |  |  void inc_counter(T& counterObj, std::decay_t<decltype(counterObj.increase())>* = nullptr) {
 | 
	
		
			
				|  |  | -  counterObj.increase();
 | 
	
		
			
				|  |  | +    counterObj.increase();
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  void doSomething() {
 | 
	
		
			
				|  |  | -  Counter cntObj;
 | 
	
		
			
				|  |  | -  uint32_t cntUI32;
 | 
	
		
			
				|  |  | +    Counter cntObj;
 | 
	
		
			
				|  |  | +    uint32_t cntUI32;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -  // blah blah blah
 | 
	
		
			
				|  |  | -  inc_counter(cntObj);
 | 
	
		
			
				|  |  | -  inc_counter(cntUI32);
 | 
	
		
			
				|  |  | +    // blah blah blah
 | 
	
		
			
				|  |  | +    inc_counter(cntObj);
 | 
	
		
			
				|  |  | +    inc_counter(cntUI32);
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  ```
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -2556,10 +2556,10 @@ void foo(float&& a);
 | 
	
		
			
				|  |  |  ```C++
 | 
	
		
			
				|  |  |  template <typename ArgT>
 | 
	
		
			
				|  |  |  void foo(
 | 
	
		
			
				|  |  | -  ArgT&& a, 
 | 
	
		
			
				|  |  | -  typename std::enabled_if<
 | 
	
		
			
				|  |  | -    std::is_same<std::decay_t<ArgT>, float>::value
 | 
	
		
			
				|  |  | -  >::type* = nullptr
 | 
	
		
			
				|  |  | +    ArgT&& a, 
 | 
	
		
			
				|  |  | +    typename std::enabled_if<
 | 
	
		
			
				|  |  | +        std::is_same<std::decay_t<ArgT>, float>::value
 | 
	
		
			
				|  |  | +    >::type* = nullptr
 | 
	
		
			
				|  |  |  );
 | 
	
		
			
				|  |  |  ```
 | 
	
		
			
				|  |  |  
 |