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