Skip to content

Commit bc55ce3

Browse files
committed
constexpr++
1 parent 3a9beaf commit bc55ce3

3 files changed

Lines changed: 66 additions & 9 deletions

File tree

‎cpp/constexpr.cpp‎

Lines changed: 63 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,14 +40,36 @@ C++11 specifies that the body of a constexrp function must contain a single retu
4040
4141
Otherwise, it would be too much work for the compiler to do.
4242
43-
<http://stackoverflow.com/questions/3226211/why-is-it-ill-formed-to-have-multi-line-constexpr-functions>
43+
http://stackoverflow.com/questions/3226211/why-is-it-ill-formed-to-have-multi-line-constexpr-functions
44+
45+
C++ 14 lifts it.
46+
47+
constexpr functions have several restrictions: in broad terms, they cannot have side effects:
48+
https://stackoverflow.com/questions/5112305/why-not-to-declare-a-function-constexpr
49+
which is cool, feels like functional pure functions.
4450
*/
45-
/*
51+
#if __cplusplus >= 201402L
4652
constexpr int constexpr_func_multi_statement(int i) {
47-
int j;
53+
// ERROR: cannot have uninitialized vars.
54+
//int j;
55+
// ERROR: cannot call non constexpr functions
56+
//std::time(NULL);
4857
return i;
4958
}
50-
*/
59+
#endif
60+
61+
class MyClass {
62+
public:
63+
MyClass() : i(1) {}
64+
constexpr MyClass(int i) : i(i) {}
65+
// ERROR: Nah.
66+
//MyClass(int i) : i(i) {}
67+
int i;
68+
constexpr int f(int j) const { return this->i + j; }
69+
constexpr int noThis(int j) const { return j + 1; }
70+
int nonConst() const { return std::time(NULL); }
71+
};
72+
5173

5274
constexpr int ConstexprFactorial(int n) {
5375
return (n == 1) ? 1 : n * ConstexprFactorial(n - 1);
@@ -92,9 +114,38 @@ int main() {
92114
// constexpr functions only work if all their arguments are constexprs.
93115
{
94116
{ constexpr int i = constexpr_func(1); }
117+
// ERROR
95118
//{ constexpr int i = constexpr_func(std::time(NULL)); }
96119
}
97120

121+
// constexpr object
122+
{
123+
constexpr MyClass myClass(1);
124+
MyClass myClassNonConst;
125+
126+
// ERROR: not using constexpr constructor on constexpr object.
127+
//{ constexpr MyClass myClass; }
128+
129+
// Fine with non constexpr constructor.
130+
131+
// Now we can use members further constexpr chains.
132+
{ constexpr int i = myClass.i; }
133+
// ERROR
134+
//{ constexpr int i = myClassNonconst.i; }
135+
136+
// Methods that don't use this don't need the constexpr object.
137+
{ constexpr int i = myClassNonConst.noThis(1); }
138+
// But if the method uses this, then it needs.
139+
{ constexpr int i = myClass.f(1); }
140+
// ERROR
141+
//{ constexpr int i = myClassNonConst.f(1); }
142+
143+
// Can still call non constexpr methods of the const object.
144+
{ int i = myClass.nonConst(); }
145+
// ERROR But not initialize constexpre expressions with them.
146+
//{ constexpr int i = myClass.nonConst(); }
147+
}
148+
98149
// Recursive functions can be constexpr, as long as they fit into one line.
99150
{
100151
constexpr int i = ConstexprFactorial(3);
@@ -122,9 +173,15 @@ int main() {
122173
//i = 1;
123174
}
124175

176+
// constexpr do have addresses. But likely they will inlined when addresses are never taken.
125177
{
126-
constexpr int i = 0;
127-
&i;
178+
constexpr int i = 1;
179+
constexpr int j = 2;
180+
const int *ip = &i;
181+
const int *jp = &j;
182+
assert(*ip == 1);
183+
assert(*jp == 2);
184+
assert(ip != jp);
128185
}
129186

130187
// WARN: unitialized constexpr

‎cpp/most_vexing_parse.cpp‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ int main() {
2020
/*
2121
BAD
2222
23-
Declares *FUNCTION* called `c` that returns `Class` inside function main.
23+
Declares *FUNCTION* called `c` that returns `C` inside function main.
2424
2525
This is the same as in C, where it is possible to declare a function from inside another function,
2626
but not define it.
@@ -32,7 +32,7 @@ int main() {
3232
C c();
3333

3434
// ERROR: function definition is not possible inside another function.
35-
//Class c() {return Class();}
35+
//C c() {return C();}
3636

3737
//c.i;
3838
}

‎cpp/tuple.cpp‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ int main() {
111111
{
112112
#if __cplusplus >= 201703L
113113
auto tuple = std::make_tuple(1, 'a', 2.3);
114-
auto [ i, c, d ] = tuple;
114+
auto [i, c, d] = tuple;
115115
assert(i == 1);
116116
assert(c == 'a');
117117
assert(d == 2.3);

0 commit comments

Comments
 (0)