Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 791fbd5

Browse files
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+
}

‎1_STL_introduction/1_9_1_config3.cpp‎

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+
}

‎1_STL_introduction/1_9_1_config5.cpp‎

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+
}

‎1_STL_introduction/1_9_1_config6.cpp‎

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+
}

‎1_STL_introduction/1_9_1_config8.cpp‎

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)

AltStyle によって変換されたページ (->オリジナル) /