Reputation: 420
Suppose you need to access a member of a struct/class either via the class literal, or through an inherited object of that class. It might looks something like this:
struct Component {
static const long key = 0;
virtual long getKey() {return key;};
};
struct FooComponent : Component {
static const long key = 0x1;
virtual long getKey() {return key;};
};
struct BarComponent : Component {
static const long key = 0x2;
virtual long getKey() {return key;};
};
With the above, key
can be accessed either via:
long key = FooComponent::key;
or
FooComponent foo;
long key = foo.getKey();
Now my question is: is there some cleaner, less redundant way of achieving the above? Ideally virtual long getKey() {return key;};
would only need to be specified once, not for every inherited class.
EDIT:
Class hierarchy is important. The components are stored in a single container, in my case an unordered_map:
std::unordered_map<long, std::unique_ptr<Component>> components;
Upvotes: 1
Views: 73
Reputation: 4387
Extending @iavr's answer to the new requirements:
struct Component {
virtual ~Component() {}
virtual long getKey() { return 0; }
};
template <int Key>
struct KeyedComponent : Component {
long getKey() { return Key; };
};
struct FooComponent : KeyedComponent<1> { };
struct BarComponent : KeyedComponent<2> { };
Tested with:
std::vector<std::unique_ptr<Component>> components;
components.emplace_back(new FooComponent());
components.emplace_back(new BarComponent());
for (auto& component : components) {
std::cout << component->getKey() << std::endl;
}
Prints:
1
2
Upvotes: 2
Reputation: 7637
Static polymorphism is your friend here:
template <long K = 0>
struct Component {
static constexpr long key = K;
long getKey() {return key;};
};
struct FooComponent : Component <0x1> {};
struct BarComponent : Component <0x2> {};
Upvotes: 2