C++ Library Extensions 2022.12.09
To help learn modern C++ programming
041-tight_control.cpp
Go to the documentation of this file.
1#include <tpf_output.hpp>
2
5
6template<typename Type> // Type - is called template parameter
7void function(Type arg) // arg - is called function-call (template) parameter
8 // function-call parameter
9{
10
11}
12
14{
15
16 int m = 5;
17
18 function<int> // type in the angle bracket <int> is called template argument
19 (m); // m is called function-call argument
20
21 double d = 5.0;
22
23 function<double&>(d);
24
25 // <double&> is template argument
26 // d is function-call argument
27
28}
29/*
30 In modern C++, parameter and argument are used differently.
31 In older C/C++, parameter and argument are synonyms.
32 */
33
34template<typename Type> // Type is template parameter
36{
37 private:
38 Type m_member; // The type of Type and the type of m_member
39 // are always... always the same.
40
41 /*
42 The type of Type and the type of m_member are always the same.
43
44 The allowed types for Type and m_member are
45
46 int - non-reference type
47 int& - lvalue reference type
48
49 of course, const int, const double, etc. allowed
50 but int&& - rvalue refernce is not allowed.
51 */
52 public:
53 NonReferenceMember(Type member): // int&& 10
54 m_member { member } { }
55
56 void report()
57 {
58 stream << "Type of Type: " << Tpf_GetTypeName(Type) << endl;
59 stream << "Type of m_member: " << Tpf_GetTypeCategory(m_member) << endl;
60 }
61};
62
63template<typename Type>
65{
66 private:
67 Type m_member; // the type of Type and the type of m_member
68 // are always the same
69
70 /*
71
72 Again, the type of Type and the type of m_member
73 are always the same.
74
75 All possible types in C++ are allowed for Type and m_member type.
76
77 */
78
79 public:
81 m_member {
82 // std::forward<Type>(member)
83 std::forward< decltype(member) >(member)
84 } { }
85
86 void report()
87 {
88 stream << "Type of Type: " << Tpf_GetTypeName(Type) << endl;
89 stream << "Type of m_member: " << Tpf_GetTypeCategory(m_member) << endl;
90 }
91};
92
94{
95 // this works successfully
97 m1.report();
98
99 // this does not work.
100 // NonReferenceMember<int&&> m2{10};
101
102 /*
103 NonReferenceMember(Type member):
104 m_member { member } { }
105 */
106
107 int&& member = 10; // the type of member is rvalue reference
108 // but its value category is lvalue
109
110 // this does not work,
111 // int&& m_member = member; // you are assigning lvalue to rvalue reference
112 // this is illegal in C++
113
114 // int&& m_member = std::forward<int>(member);
115 int&& m_member = std::forward<int&&>(member);
116 // int&& m_member = std::forward< decltype(member) > (member);
117 // int&& m_member = std::move(member);
118
119 // it works ...
121 m3.report();
122
123}
124
126{
127 int m = 5;
128
130 m1.report();
131
133 m2.report();
134
135 // it does not work
136 // NonReferenceMember<int&&> m3{ 5 };
137
138 stream << endl;
139
141 m4.report();
142
144 m5.report();
145
147 m6.report();
148}
149
150template<typename Type>
152{
153 private:
154 Type& m_member; // At first glance, the type of Type
155 // and the type of m_member might seem always different.
156
157 // But that is not true...
158 // the type of Type can be int&,
159 // the type of m_member can also be int&
160 //
161 // that is, the type of Type and the type of m_member can be the same
162
163 /*
164
165 One thing we can say for sure is that
166
167 both the type of Type and the type of m_member can never be
168 rvalue reference type.
169
170 */
171
172 /*
173 If the type of Type is int,
174
175 Type = int,
176
177 int& m_member,
178
179 So, the type of Type is int
180 the type of m_member is int&
181
182
183 */
184
185};
186
187template<typename Type>
189{
190 private:
191 Type&& m_member;
192
193 // The type of Type can be int, int&, int&&.
194 // the type of m_member can be int& and int&&, but can never be int.
195
196};
197
198
199int main()
200{
201 // test_non_reference_member_classes();
202
204}
void test_function_call()
void function(Type arg)
void comparison_of_two_classes()
tpf::sstream stream
void test_non_reference_member_classes()
auto endl
int main()
NonReferenceMember(Type member)
constexpr auto endl
Definition: tpf_output.hpp:973
Stream output operators << are implemented.
#define Tpf_GetTypeName(type_arg)
A macro that returns type_arg's string name.
Definition: tpf_types.hpp:1422
#define Tpf_GetTypeCategory(instance_arg)
A macro that returns instance_arg's type category string name.
Definition: tpf_types.hpp:1428