I tried this test to see if I could supply default values in a template argument. The code below compiles without any issues. However, _1 and _2 are not being initialized to the default value constant. Why isn't this working? Am I overlooking something obvious?
template<typename T, T defaultValue>
struct DefaultTest
{
private:
T _1;
T _2;
public:
const T _default = defaultValue;
DefaultTest() : _1(_default), _2(_default) { } // not working
inlineconst T value1() const { return _1; }
inlineconst T value2() const { return _2; }
};
int main()
{
DefaultTest<int, 10> n = DefaultTest<int, 10>();
DefaultTest<int, 10> m = DefaultTest<int, 10>();
int x = n.value1();
int y = m.value1();
return 0;
}
The values of x and y at runtime suggest that _1 and _2 are not being initialized at all. It should be noted that explicitly assigning them in the body of the constructor works just fine.
_default is a non-static member and it's declared after _1 and _2, so its value is being initialized after _1 and _2 have been initialized. If you want it to be non-static you should move it up in the class definition. IMO it should probably be a static constant.
Huh. I thought constants were static. I know they are in C#. I haven't used c++ constants in a very long time. I am curious why a constant wouldn't be static but since c++ doesn't have a readonly type, it makes sense.
In C# you can't take the address of a value, so you can't tell where a value is being stored (and most values are stored in the heap anyway).
In C++, whether a member is static or non-static has externally observable behavior. For example, the size of the class and the memory layout of the members change. So the compiler can't make it static if you don't tell it to.