I assume that this is because in the first case the compiler literally sticks to the value, while in the second case the function requires an address that does not yet exist without redefinition. If so, is that what I am saying is this declaration really a definition?
You have already answered the question. Static members are defined outside the class, so you have a definition. When you pass this to a function, an address is needed, so you need to define a static member. Although in your first case, the compiler simply replaces Foo::bar with a value.
Now replace the function signature as follows:
int returnconstexpr(int x) { return x; }
In the above case, you no longer need a definition.
The rule for this in 3.2 of the C ++ standard:
The variable x whose name is displayed as a potentially evaluated expression ex is used by odr if x is not an object that satisfies the requirements for displaying in constant expression (5.19), and ex is an element of the set of potential results of expression e, where either lvalue-to-rvalue conversion (4.1) applied to e or e is the expression of the reset value (section 5).
In the above case, the lvalue-rvalue conversion is immediately applied, and therefore it is not used by odr (as specified in the standard), and no definition is required. In simple words, this means that it can simply use the value and does not need to know the address, however, when you use the reference type (const int &), it requires the compiler to know where the object is in memory.
Jesse good
source share