Reputation: 671
In C++14 and beyond, constexpr
for member functions no longer implies const
.
struct Value
{
int i = 5;
constexpr bool not_five() // requires const to compile
{
return this->i != 5;
}
};
int main()
{
constexpr Value v{6};
static_assert(v.not_five());
}
error: passing ‘const Value’ as ‘this’ argument discards qualifiers [-fpermissive]
static_assert(v.not_five());
^
It seems as though calling a non-const constexpr member function at compile time implies the mutation of a constant, since the object it's called against exists at compile time and is being mutated. Under what circumstances is the concept of a non-const constexpr member function useful?
Upvotes: 5
Views: 183
Reputation: 671
It seems that I inadvertently duplicated this question as well as this other one. Based on their answers, there are (at least) two concrete scenarios in which a non-const constexpr member function is useful.
Mutation of temporaries. It is permissible to mutate a temporary value at compile time; it only becomes constant upon assignment.
Mutation of objects during function execution. While executing, a constexpr function might create an object instance and then mutate it via member functions. Those member functions can't be called at compile time unless they're constexpr, but they can't mutate the instance they're called against if they're const.
struct Value
{
int i{};
constexpr Value add(int n)
{
this->i += n;
return *this;
}
constexpr Value add(Value other) const
{
Value ret{this->i};
ret.add(other.i); // call to non-const constexpr member
return ret;
}
};
int main()
{
constexpr Value v = Value{}.add(1);
// v.add(1); // illegal
constexpr Value u = v.add(v);
}
Upvotes: 2