As expected, I can compile the sample below without any problems
// first_sample.cpp
struct sample_struct
{
constexpr int
sample_method()
{ return 5; }
};
int main()
{
sample_struct sample_object;
constexpr int sample_variable = sample_object.sample_method();
return 0;
}
But i cannot compile the following sample for the reason
'this' is not a constant expression
// second_sample.cpp
struct sample_struct
{
constexpr int
sample_method_first()
{ return 5; }
void
sample_method_second()
{ constexpr int sample_variable = sample_method_first();
/* Do something with sample_variable */ }
};
int main()
{ return 0; }
I already know how to solve this "problem" so i am not asking for a solution. I am asking for a reasonable explanation why i am allowed to call a constexpr method from a non-constexpr object while i am not allowed to call the same constexpr method inside another method (from non-constexpr 'this').
In the C++ Standard, [dcl.constexpr]/9:
A constexpr specifier used in an object declaration declares the object as const. Such an object shall have literal type and shall be initialized. [...] Otherwise, or if a constexpr specifier is used in a reference declaration, every full-expression that appears in its initializer shall be a constant expression.
Now, the compiler implicitly adds a this->
to the member function call, as specified by [expr.call]/1
In the case of an implicit class member access, the implied object is the one pointed to by this. [Note: a member function call of the form
f()
is interpreted as(*this).f()
(see 9.3.1). —end note ]
As jogojapan has pointed out (see chat discussion), in the official C++11 Standard, this
may occur as postfix-expression in a class member access as per [expr.const]/2, which is the case here. But the resolution of Issue 1369 disallowed any use of this
in constant expressions; however function invocation substitution can allow using this
within the context of a constexpr
function by replacing it with a prvalue pointer.
The C++14 draft removes the sub-paragraph about function invocation substitution in favour of an exception to [expr.const]/2, explicitly allowing the use of this
within the context of a constexpr
function (in this case effectively the same as what function invocation substitution allowed).
Well, this isn't very "reasonable" as it doesn't provide the reason why it is specified in this way, it only provides the reason why the compiler rejects it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With