if you do this:
constexpr int LEN = 100;
LEN
variable defined as const
without need of typing const
keyword.
It also have static
storage, without need to type static
keyword.
From the other hand, if we do same in class
:
struct A{
constexpr static int SIZE = 100;
};
SIZE
is still defined as const
without need of typing const keyword,
However SIZE
is not static
data member.
You need to type static
explicitly. If you don't there will be compilation error.
Question is:
What is the reason of need to explicitly type static
?
static
doesn't have same signification in both context :
LEN
, static
means "only available in this compilation unit", so only internal linkage. It's a storage specifier
A::SIZE
, static
means "it's a class member", so not bound to specific instancesconstexpr
in class context can refer to instance or class member or function, so compiler can't determine at your place if it's static
or not, ie bound or not to a specific instance. It's same reasoning as const
specifier. But, as you can imagine, it's a non-sense to have a non-static constexpr
member, so it's forbidden. Example :
class A
{
int a;
constexpr A(int value): a(value) {}
// constexpr bound to a specific instance
constexpr int getDouble() const
{ return a*2; }
// constexpr not bound to a specific instance
static constexpr int getDouble(int b)
{ return b*2; }
}
constexpr
in global context refers to something which will be calculated at compile time (or, for function, if not possible to calculate at compile time, which will be inlined), so no need of external linkage and so, comparable behavior as a static
global variable or function (only comparable because, with compile time calculation or inlining, you also don't need internal linkage)
constexpr int a = 5; // Will be replace everywhere by value
/* If b is constexpr, calcul are done at compile time and result will be used
* else double is inlined, so no need of linkage at all
*/
constexpr int getDouble(int b)
{ return b * 2; }
constexpr
should not imply static
, because having constexpr
without static
makes sense. Consider:
#include <iostream>
struct Dim
{
constexpr Dim(int a,int b) : a(a), b(b) {}
constexpr int Prod() const { return a*b; }
int a,b;
};
int main()
{
constexpr Dim sz(3,4);
int arr[ sz.Prod() ];
std::cout << sizeof(arr) << std::endl;
}
It should also not imply static
outside of class definition
since static
there means 'local to translation unit' and constexpr
does not require that.
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