@@ -40,14 +40,36 @@ C++11 specifies that the body of a constexrp function must contain a single retu
4040
4141Otherwise, 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
4652constexpr 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
5274constexpr 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
0 commit comments