There are a numbe of things not conforming to the C++ specifications, here:
1) The initialization of a variable of non integral type must be at file level
2) initializing a struct with a brace initilializer list requires the struct to be a POD (POD = Plain Old Data)
To accommodate 1) you must move the initialization outside of the class declaration and to accommodate 2) you must have no constructors.
In this way it works
struct AsVarVal
{
bool isVar;
unsigned char varVal;
const static AsVarVal Default;
};
const AsVarVal AsVarVal::Default = {false, 0};
If you want to have constructors, you may have a different approach, like this
struct AsVarVal
{
bool isVar;
unsigned char varVal;
AsVarVal() :isVar(false), varVal(0)
{}
AsVarVal(bool isVar_, unsigned char varVal_)
:isVar(isVar_), varVal(varVal_)
{}
};
[Edit in answer to the comment]
About 1) I meant "conformant to the language specification".
Something none of us wrote. They simply "are".
About 2) Yes, you got it right. About the "why", this is exactly the same rule that says that declarations can be repeated (since they don't instantiate anything, just define symbols for the compiler) but definition cannot.
Why this rule exist, and why C++ use headers as "paste in" (not as "symbols catalogs", like other languages do) ... that's how C++ specification are. The "why" is that C++ must be backward compatible with C that is -in turn- an "high level assembler". And that's how C works.
Note that what you call "class definition" (in 4) ) is in fact a "declaration": it doesn't instantiate any object, it just tells how the class is structured, but doesn't allocate any space for it. It just says how much of it is required.
But an initialized static variable is a definition, since it requires some space to be reserved for it.
Integral constants -in this context- are an exception to that general rule that can be tolerated just because integrals are evaluated by the compiler itself (in fact an integral constant is not allocated as an object: it is just a number that will replace the constant symbol in every place it is used). The reason of this exception resides in the fact that operation taking an integer as a parameter can be translated directly in a single machine code instruction on the most of the processors. Other type of constants don't fit a single instruction and require a reference or a data move (and hence "space" in the data memory)
About 3) The term "Plain Old Data" (abbreviated as POD) is what the C++ language specs calls "a struct that conforms to the C subset specs C++ is based on". Essentially C struct (with no constructor, destructor, access specifiers, virtual methods etc.)
About 4) I can understand your feeling (C++ is not a simple language...), but -technically speacking- my solutions aren't workarounds: they are nothign more that what the language specifications require.
By looking at your code, it seems you are using C++ as it is Java or C#.
C++ is a completely different language with a completely different philosophy. That leads to a completely different coding style and patterns implementation.