mirror of
https://github.com/wuye9036/CppTemplateTutorial.git
synced 2024-03-22 13:11:16 +08:00
commit
272c88c9ff
226
ReadMe.md
226
ReadMe.md
|
@ -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,
|
||||
typenname 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
|
||||
);
|
||||
```
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user