How can I create a C++ basic type that self-initializes?
c++, c++11
Solution
#include <unordered_map>
#include <iostream>
using namespace std;
template<typename T, T default_value>
class SelfInitializer
{
public:
SelfInitializer(T x = default_value) : x(x) {}
operator T&() { return x; }
operator const T&() const { return x; }
private:
T x;
};
// demo
int main()
{
using minus1 = SelfInitializer<int, -1>;
unordered_map<int, minus1> m;
m[7] = 3; // assignment works
minus1 x = 3;
int y = x; // conversion to int works
int z = int(x); // explicit conversion works
cout << m[7] << endl;
}
Problem
Related question: std::map default value for build-in type -- the subtle difference is I want more than to know whether the value is initialized to `0` or garbage, I want to specify a "constructor". I don't even care if it involves overhead with a class definition, I just want a clean "special" basic type. Even a syntactical hack would do. A non basic type is very easy to do this for, it is the entire job of the constructor. I'd like to have a hashmap `unordered_map<void *, int>` but to have all its values default-initialized to `-1` instead of `0` or garbage. This is because zero is a valid index, and I would prefer to default-initialize with a certainly invalid value. I think I see a few sloppy ways this might be done with: ``` struct minus1 { int i; minus1() i(-1) {} }; unordered_map<void*, minus1> ``` But I don't like this because I have to use `.i` to access the int, and it really just needs to be an int. Okay so maybe I can have my map handle this: ``` struct PointerToIDHash { std::unordered_map<void *, int> h; PointerToIDHash() { // ctor is powerless to affect the initialized values of future insertions into h } }; ``` Well, crap now I have a `.h` too. Uhhhh. Can I inherit from a template? (sounds scary, but this might be a clean way if it can be pulled off) How can I make a type that transparently acts like an int but is always initialized to `-1`? I would prefer to know both how to do this with and without C++11.