Having a constexpr constructor does not make declarations of that variable automatically constexpr, so t
is not a constexpr. What is going on in this case is that you are calling a constexpr function, this line:
constexpr int b = t+test();
can be viewed as follows:
constexpr int b = t.operator+( test() );
So then the question is whether test()
is a constant expression, which it is since the constructor is constexpr and does not fall under any of the exceptions under the draft C++11 standard section 5.19
[expr.const] paragraph 2
which says:
A conditional-expression is a core constant expression unless it
involves one of the following as a potentially evaluated subexpression
[...]
and includes the following bullet:
- an invocation of a function other than a constexpr constructor for a literal class or a constexpr function [ Note: Overload resolution
(13.3) is applied as usual —end note ];
[...]
an invocation of a constexpr constructor with arguments that, when substituted by function invocation
substitution (7.1.5), do not produce all constant expressions for the constructor calls and
full-expressions in the mem-initializers
an invocation of a constexpr function or a constexpr constructor that would exceed the implementationdefined
recursion limits (see Annex B);
We can see this more readily by making some small changes to test
by introducing a member variable x
:
class test{
public:
constexpr test(){
}
constexpr int operator+(const test& rhs) const {
return x + 1 ;
}
int x = 10 ;
};
Attempting to access it in operator +
and we can see that the following line now fails:
constexpr int b = t+test();
with the following error from clang (see it live):
error: constexpr variable 'b' must be initialized by a constant expression
constexpr int b = t+test(); // works at compile time!
^ ~~~~~~~~
note: read of non-constexpr variable 't' is not allowed in a constant expression
return x + 1 ;
^
It fails because t
is not a constexpr variable and therefore its subobjects are also not constexpr variables.
Your second example:
constexpr int c = w + 2;
does not work because it falls under one of the exceptions in the draft C++11 standard section 5.19
[expr.const] :
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…