Skip to content

Commit 791fbd5

Browse files
committed
Upload note code of chapter 1 introduction
1 parent 257f509 commit 791fbd5

14 files changed

+622
-0
lines changed
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
// file: 1config-null-template-arguments.cpp
2+
// test __STL_NULL_TMPL_ARGS in <stl_config.h>
3+
// ref. C++ Primer 3/e, p.834: bound friend function template
4+
// vc6[x] cb4[x] gcc[o]
5+
6+
// 直接理解为若允许**bound friend template(约束模板友元)**
7+
// 则定义为 <> ,否则为空。
8+
// friend bool ooperator== __STL_NULL_TMPL_ARGS(const stack&,const stack&);
9+
// 展开后变成
10+
// friend bool ooperator== <>(const stack&,const stack&);
11+
// 友元类型取决于类被初始化时的类型,但程序必须在类外为友元提供模板定义。
12+
13+
#include <iostream>
14+
#include <cstddef> // for size_t
15+
using namespace std;
16+
17+
class alloc {
18+
};
19+
20+
// BufSiz为非类型参数
21+
template <class T, class Alloc=alloc, size_t BufSiz=0>
22+
class deque {
23+
public:
24+
deque() {
25+
cout << "deque" << " ";
26+
}
27+
};
28+
29+
//以㆘宣告如果不出现,GCC也可以通过。如果出现,GCC也可以通过。这㆒点和
30+
// C++ Primer 3/e p.834的说法有出入。书㆖说㆒定要有这些前置宣告。
31+
template <class T, class Sequence>
32+
class stack;
33+
34+
template <class T, class Sequence>
35+
bool operator==(const stack<T, Sequence> &x,
36+
const stack<T, Sequence> &y);
37+
38+
template <class T, class Sequence>
39+
bool operator<(const stack<T, Sequence> &x,
40+
const stack<T, Sequence> &y);
41+
42+
template <class T, class Sequence = deque<T>>
43+
class stack {
44+
// 以下三种写法都可以,即标注模板的使用
45+
friend bool operator== <T> (const stack<T> &, const stack<T>&);
46+
friend bool operator< <T> (const stack<T> &, const stack<T> &);
47+
48+
friend bool operator== <T> (const stack &, const stack &);
49+
friend bool operator< <T> (const stack &, const stack &);
50+
51+
friend bool operator== <> (const stack &, const stack &);
52+
friend bool operator< <> (const stack &, const stack &);
53+
54+
// 编译报错,提示如下
55+
// note: (if this is not what you intended, make sure the function template has already been declared and add <> after the function name here)
56+
// friend bool operator== (const stack &, const stack &);
57+
// friend bool operator< (const stack &, const stack &);
58+
59+
public:
60+
stack() {
61+
cout << "stack" << endl;
62+
}
63+
private:
64+
Sequence c;
65+
};
66+
67+
template <class T, class Sequence>
68+
bool operator==(const stack<T, Sequence> &x,
69+
const stack<T, Sequence> &y) {
70+
// error: cannot convert 'std::basic_ostream<char>' to 'bool' in return
71+
// return cout << "operator==" << '\t';
72+
cout << "operator==" << '\t';
73+
return true;
74+
}
75+
76+
template <class T, class Sequence>
77+
bool operator<(const stack<T, Sequence> &x,
78+
const stack<T, Sequence> &y) {
79+
// return cout << "operator<" << '\t';
80+
cout << "operator<" << '\t';
81+
return true;
82+
}
83+
84+
int main() {
85+
stack<int> x;
86+
stack<int> y;
87+
88+
cout << (x == y) << endl;
89+
cout << (x < y) << endl;
90+
91+
stack<char> y1;
92+
// error: no match for 'operator==' (operand types are 'stack<int>' and 'stack<char>')
93+
// cout << (x == y1) << endl;
94+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
// file: 1config-template-exp-special.cpp
2+
// 以下测试 class template explicit specialization
3+
// test __STL_TEMPLATE_NULL in <stl_config.h>
4+
// ref. C++ Primer 3/e, p.858
5+
// vc6[o] cb4[x] gcc[o]
6+
7+
// template <> 显示的模板特化(class template explicit specialization)**
8+
// 即指定一种或多种模板形参的实际值或实际类型,作为特殊情况。(与模板类型偏特化不同!)
9+
10+
#include <iostream>
11+
using namespace std;
12+
13+
#define __STL_TEMPLATE_NULL /* blank */
14+
15+
template <class Key> struct hashes {
16+
void operator() () {
17+
cout << "hashes<T>" << endl;
18+
}
19+
};
20+
21+
// 以下注释编译不通过,必须遵守c++标准规格,即写出template<>
22+
// error: an explicit specialization must be preceded by 'template <>'
23+
24+
// explicit specialization
25+
// __STL_TEMPLATE_NULL struct hashes<char>{
26+
// void operator()(){
27+
// cout << "hashes<char>" << endl;
28+
// }
29+
// };
30+
31+
// __STL_TEMPLATE_NULL struct hashes<unsigned char>{
32+
// void operator()(){
33+
// cout << "hashes<char>" << endl;
34+
// }
35+
// };
36+
37+
int main() {
38+
hashes<long> t1;
39+
hashes<char> t2;
40+
hashes<unsigned char> t3;
41+
42+
t1();
43+
t2();
44+
t3();
45+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// file: 1config10.cpp
2+
// 测试 template参数可否根据前㆒个 template参数而设定默认值。
3+
// test __STL_LIMITED_DEFAULT_TEMPLATES in <stl_config.h>
4+
// ref. C++ Primer 3/e, p.816
5+
// vc6[o] cb4[o] gcc[o]
6+
7+
// 如果编译器支持一个template参数可以根据前一个template的参数设置就定义。
8+
9+
#include <iostream>
10+
#include <cstddef> // for size_t
11+
using namespace std;
12+
13+
class alloc {
14+
};
15+
16+
template <class T, class Alloc=alloc, size_t BufSiz=0>
17+
class deque {
18+
public:
19+
deque() {
20+
cout << "deque()" << endl;
21+
}
22+
};
23+
24+
template <class T, class Sequence = deque<T>>
25+
class stack {
26+
public:
27+
stack() {
28+
cout << "stack" << endl;
29+
}
30+
private:
31+
Sequence c;
32+
};
33+
34+
int main() {
35+
stack<int> x;
36+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// file: 1config11.cpp
2+
// 测试 class template可否拥有 non-type template参数。
3+
// test __STL_NON_TYPE_TMPL_PARAM_BUG in <stl_config.h>
4+
// ref. C++ Primer 3/e, p.825
5+
// vc6[o] cb4[o] gcc[o]
6+
7+
// 测试类模板是否使用非类型模板参数(non-type template parameters) 。
8+
// 当以类型 (type)作为模板参数的时候,代码中未决定的是类型;
9+
// 当以一般的数字(non-type)作为模板参数的时候,代码中待定的内容便是某些数值。使用者这种模板必须要显示指定数值,模板才能实例化。
10+
// 通常它们只能是常数整数(constant integral values )包括枚举,或者是指向外部链接的指针。
11+
// 不能把float,class-type类型的对象,内部链接(internal linkage )对象,作为非类型模板参数。
12+
13+
#include <iostream>
14+
#include <cstddef> // for size_t
15+
using namespace std;
16+
17+
class alloc {
18+
};
19+
20+
inline size_t __deque_buf_size(size_t n, size_t sz) {
21+
return n != 0 ? n : (sz < 512 ? size_t(512 / sz) : size_t(1));
22+
}
23+
24+
template <class T, class Ref, class Ptr, size_t BufSiz>
25+
struct __deque_iterator {
26+
typedef __deque_iterator<T, T&, T*, BufSiz> iterator;
27+
typedef __deque_iterator<T, const T&, const T*, BufSiz> const_iterator;
28+
static size_t buffer_size() {
29+
return __deque_buf_size(BufSiz, sizeof(T));
30+
}
31+
};
32+
33+
// BufSiz为非类型参数
34+
template <class T, class Alloc=alloc, size_t BufSiz=0>
35+
class deque {
36+
public:
37+
typedef __deque_iterator<T, T &, T *, BufSiz> iterator;
38+
};
39+
40+
int main() {
41+
cout << deque<int>::iterator::buffer_size() << endl;
42+
// 非类型参数64
43+
cout << deque<int, alloc, 64>::iterator::buffer_size() << endl;
44+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// file: 1config3.cpp
2+
// 测试在 class template中 拥有 static data members.
3+
// test __STL_STATIC_TEMPLATE_MEMBER_BUG, defined in <stl_config.h>
4+
// ref. C++ Primer 3/e, p.839
5+
// vc6[o] cb4[x] gcc[o]
6+
// cb4 does not support static data member initialization.
7+
8+
// 如果编译器无法处理static member of template classes(模板类静态成员)就定义。
9+
// 即对于模板类中,模板类型不同时的静态变量不同。
10+
11+
#include <iostream>
12+
using namespace std;
13+
14+
template <typename T>
15+
class TestClass {
16+
public:
17+
static int _data;
18+
};
19+
20+
// 需要加上template<>,否则编译出错,进行内存配置
21+
template<> int TestClass<int>::_data = 1;
22+
template<> int TestClass<char>::_data = 1;
23+
24+
int main() {
25+
26+
cout << TestClass<int>::_data << endl;
27+
cout << TestClass<char>::_data << endl;
28+
29+
TestClass<int> obji1, obji2;
30+
TestClass<char> objc1, objc2;
31+
cout << obji1._data << " " << obji2._data << endl;
32+
cout << objc1._data << " " << objc2._data << endl;
33+
34+
obji1._data = 3;
35+
objc2._data = 4;
36+
37+
cout << obji1._data << " " << obji2._data << endl;
38+
cout << objc1._data << " " << objc2._data << endl;
39+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
// file: 1config5.cpp
2+
// 测试 class template partial specialization
3+
// — 在 class template的一般化设计之外,特别针对某些 template参数做特殊设计。
4+
// test __STL_CLASS_PARTIAL_SPECIALIZATION in <stl_config.h>
5+
// ref. C++ Primer 3/e, p.860
6+
// vc6[x] cb4[o] gcc[o]
7+
8+
// 如果编译器支持 partial specialization of class templates(模板类偏特化)就定义。
9+
// 在模板类一般化设计之外(全特化),针对某些template做特殊设计。
10+
// “所谓的partial specialization的另一个意思是提供另一份template定义式,而其本身仍是templatized”
11+
// 全特化就是所有的模板都为具体的类。
12+
// T* 特化允许用指针类型匹配的模式(也只能匹配指针类型)。
13+
// const T* 特化允许使用指向const的指针 类型匹配(也只能匹配指向const的指针)。
14+
15+
#include <iostream>
16+
using namespace std;
17+
18+
// 一般化设计
19+
template <class I, class O>
20+
struct TestClass {
21+
TestClass() {
22+
cout << "I, O" << endl;
23+
}
24+
};
25+
26+
// 特殊化设计
27+
template <class T>
28+
struct TestClass<T*, T*> {
29+
TestClass() {
30+
cout << "T*, T*" << endl;
31+
}
32+
};
33+
34+
// 特殊化设计
35+
template <class T>
36+
struct TestClass<const T*, T*> {
37+
TestClass() {
38+
cout << "const T*, T*" << endl;
39+
}
40+
};
41+
42+
int main() {
43+
TestClass<int, char> obj1;
44+
TestClass<int *, int *> obj2;
45+
TestClass<const int *, int *> obj3;
46+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// file: 1config6.cpp
2+
// test __STL_FUNCTION_TMPL_PARTIAL_ORDER in <stl_config.h>
3+
// vc6[x] cb4[o] gcc[o]
4+
5+
// 如果编译器支持partial ordering of function templates
6+
// 或者说partial specialization of function templates就定义。
7+
8+
#include <iostream>
9+
using namespace std;
10+
11+
class alloc {
12+
};
13+
14+
template <class T, class Alloc=alloc>
15+
class vec {
16+
public:
17+
void swap(vec<T, Alloc>&) {
18+
cout << "swap()" << endl;
19+
}
20+
};
21+
22+
// inline内联函数,解决一些频繁调用的小函数大量消耗栈空间(栈内存)的问题
23+
// inline只适合函数体内代码简单的函数使用,不能包含复杂的结构控制语句例如 while、switch,并且不能内联函数本身不能是直接递归函数
24+
// 定义在类中的成员函数默认都是内联的,类外实现需加上inline
25+
#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER
26+
template <class T, class Alloc>
27+
inline void swap(vec<T, Alloc>& x, vec<T, Alloc>& y) {
28+
x.swap(y);
29+
cout << "inline swap" << endl;
30+
}
31+
#endif
32+
33+
int main() {
34+
vec<int> x, y;
35+
swap(x, y);
36+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// file: 1config8.cpp
2+
// 测试 class template之内可否再有 template (members).
3+
// test __STL_MEMBER_TEMPLATES in <stl_config.h>
4+
// ref. C++ Primer 3/e, p.844
5+
// vc6[o] cb4[o] gcc[o]
6+
7+
// 如果编译器支持template members of classes(模板类内嵌套模板) 就定义。
8+
9+
#include <iostream>
10+
using namespace std;
11+
12+
class alloc {
13+
};
14+
15+
template <class T, class Alloc=alloc>
16+
class vec {
17+
public:
18+
typedef T value_type;
19+
typedef value_type* iterator; // 迭代器为指针
20+
// typedef T *iterator; // 直接定义也可
21+
22+
template <class I> // 模板嵌套模板
23+
void insert(iterator position, I first, I last) {
24+
cout << "insert()" << endl;
25+
}
26+
};
27+
28+
int main() {
29+
int ia[5] = {0, 1, 2, 3, 4};
30+
31+
vec<int> x;
32+
vec<int>::iterator ite;
33+
x.insert(ite, ia, ia + 5);
34+
}

0 commit comments

Comments
 (0)