It seems obvious that constexpr implies const and thus it is common to see:
constexpr int foo = 42; // no const here
However if you write:<
No. To say they are the same means that there's no time that not using const would be valid without producing functionally identical code to a const version.
I find this useful in the creation of safe singletons. I haven't explored this fully, and would expect there are other valid uses for non-const constexpr.
As an example, here is code that requires non-const constexpr:
Start with a global definition of a variable:
int global_int_;
And now we can create a constexpr function that returns a reference to it:
constexpr int& get_global()
{
return global_int_;
}
Now we can use that reference somewhere else:
int main()
{
constexpr int& i{ get_global() };
// do stuff with i
return 0;
}
We can now use i
as a non-const int. If const was implied, this would not be possible.
Since non-const constexpr is valid, if you are using a constexpr that needs to be const you will need to explicitly declare it.
The error message you're seeing has nothing to do with the constexpr
keyword per se.
A string literal like "foo", as in:
somefunction("foo");
The type of this string literal is const char *
. The following statement:
char *const str = "foo";
This tries to assign a const char *
value to a char *
value. The resulting char *
value is non-mutable, constant, but by that time the error already occured: an attempt to convert a const char *
to a char *
.
The constexpr
keyword in your example is just a distraction, and has no bearing on the error.
The issue is that in a variable declaration, constexpr
always applies the const
-ness to the object declared; const
on the other hand can apply to a different type, depending on the placement.
Thus
constexpr const int i = 3;
constexpr int i = 3;
are equivalent;
constexpr char* p = nullptr;
constexpr char* const p = nullptr;
are equivalent; both make p
a const
pointer to char
.
constexpr const char* p = nullptr;
constexpr const char* const p = nullptr;
are equivalent. constexpr
makes p
a const
pointer. The const
in const char *
makes p
point to const char
.