C++ Library Extensions 2022.12.09
To help learn modern C++ programming
042-compile_time_expression.cpp
Go to the documentation of this file.
1#include <tpf_output.hpp>
2
5
6
8{
9 const int size = 10;
10
11 // In C/C++, the element count of a static array
12 // should be determined or evaluated at compile-time.
13 // According to C++ Standard, size is a constant expression,
14 // so this code works.
15 int array[size];
16}
17
18constexpr size_t get_size()
19{
20 return 10;
21}
22
24{
25 // is size a constant expression ?
26 // no, it is not.
27 const int size = get_size();
28
29 /*
30 Even though size is specified with keyword const,
31 get_size() is executed at run-time.
32 At compile-time, the value of size is unknown.
33
34 The present can affect the Future, but the present cannot know
35 the value of the Future.
36
37 The compile-time is present, the run-time is future.
38
39 The value of size should be determined or evaluated at compile-time
40 to reserve the memory for array at compile-time.
41
42 Even though size is specified with the keyword const,
43 but still its value is determined or evaluated at run-time.
44
45 Is size a constant expression? Yes or No.
46
47 Since the value of size does not change, it is a constant expression.
48 Since the value of size is not evaluated at compile-time,
49 it is not a contant expression according to C++ Standard.
50
51 If we say it as "compile-time expression," there can be no confusion.
52 */
53
54 int array[size];
55}
56
57// this is a global variable.
58// The address of any global object is evaluated or
59// determined at compile-time.
60// Global and Static local variables are stored
61// in the Data section of the generated binary code.
62// Memory for objects in Data section are determined
63// or allocated at compile-time.
64int gGlobalInt = 10;
65
66template<int* ptr> // ptr is non-type template parameter.
68{
69 return *ptr;
70}
71
73{
74 stream << "The Address of function: " << get_a_value<&gGlobalInt> << endl;
75
76 stream << "The returned value of the function: " << get_a_value<&gGlobalInt>() << endl;
77}
78
79template<auto ptr>
81{
82 return *ptr;
83}
84
86{
87 // the address of d is determined at compile-time
88 // because d is specified with the keyword static.
89 static double d;
90
91 // this code is executed at run-time.
92 d = 22.0/7.0;
93
94 stream << "The value of d = " << get_a_value_using_auto<&d>() << endl;
95}
96
98{
99 // the address of d, the local variable residing in the stack,
100 // is not determined or evaluated at compile-time,
101 // we can know the address of a local stack variable only at
102 // run-time.
103 double d = 22.0/7.0;
104
105 stream << "The value of d = "
106 // << get_a_value_using_auto< &d >()
107 // we cannot pass non-compile-time expression
108 << endl; // as non-type template arguments.
109}
110
112{
113 // In C/C++, the enumerators of an enum are compile-time expressions.
114
115 using tuple_t = std::tuple<int, double, const char*>;
116 enum: size_t{age, weight, name};
117
118 tuple_t person{ 20, 60.0, "Thomas Kim"};
119
120 stream << "I am " << std::get<name>(person)
121 << ". I am " << std::get<age>(person)
122 << " years old. "
123 << "I weigh " << std::get<weight>(person) << " kg." << endl;
124
125 size_t index = 0;
126
127 stream // << std::get<index> (person) // this code does not work.
128 // because the value of index is determined
129 // or evaluated at run-time.
130 // index is not a compile-time expression.
131 << endl;
132}
133
135{
136 using variant_t = std::variant<int, double, const char*>;
137
138 variant_t item;
139
140 item = 5;
141
142 stream << std::get<0>(item) << endl;
143
144 item = "Thomas Kim";
145
146 // stream << std::get<2>(item) << endl;
147
148 // the value of index is evaluated at run-time.
149 auto index = item.index();
150
151 // non-type template argument should be compile-time expression
152 stream // << std::get<index> (item) // this code does not work
153 << endl;
154
155 // At this point, you should wonder how I implemented
156 // stream class such that it can figure the type of item
157 // at run-time?
158 // The answer is Template Metaprogramming technique.
159 stream << item << endl;
160}
161
162int main()
163{
164 // test_const_expression();
165
166 //why_constant_expression_is_misnomer();
167
168 // test_non_type_template_parameters();
169
170 // test_get_a_value_auto();
171
172 // test_failure_case();
173
174 // important_concept_for_compile_time_expression();
175
176 why_it_fails();
177}
void important_concept_for_compile_time_expression()
void test_get_a_value_auto()
tpf::sstream stream
void test_const_expression()
auto get_a_value_using_auto()
constexpr size_t get_size()
void test_non_type_template_parameters()
void why_constant_expression_is_misnomer()
void test_failure_case()
constexpr auto endl
Definition: tpf_output.hpp:973
Stream output operators << are implemented.