I'm trying to write some metaprogramming code such that:
- Inheriting from some class
foo<c1, c2, c3, ...>
results in inheritance fromkey<c1>, key<c2>, key<c3>, ...
- The simplest approach doesn't quite work because you can't inherit from the same empty class more than once.
- Handling the "..." portion isn't pretty (since it's copy-pasta), but works.
Okay, so, here's the attempt:
template<char c0, typename THEN, typename ELSE>
struct char_if
{
typename THEN type;
};
template<typename THEN, typename ELSE>
struct char_if<0, THEN, ELSE>
{
typename ELSE type;
};
class emptyClass {};
template<char c> class key
{
char getKey(){return c;}
};
template<char c0, char c1, char c2, char c3, char c4>
class inheritFromAll
{
typename char_if<c0, key<c0>, emptyClass>::type valid;
class inherit
: valid
, inheritFromAll<c1, c2, c3, c4, 0>::inherit
{};
};
template<char c1, char c2, char c3, char c4>
class inheritFromAll<0, c1, c2, c3, c4>
{
class inherit {};
};
template<char c0 = 0, char c1 = 0, char c2 = 0, char c3 = 0, char c4 = 0>
class whatINeedToDo
: public inheritFromAll<c0, c1, c2, c3, c4>::inherit
{
bool success(){return true;}
};
int main()
{
whatINeedToDo<'A', 'B', 'c', 'D'> experiment;
return 0;
}
I had originally though I could use Boost::Mpl to do it, but I honestly couldn't figure out how; I couldn't figure how you'd pass around a list<...>
without always explicitly knowing the ...
part.
Just doing:
template<> class key<0> {};
doesn't work because if I then have more than one 0
parameter, I try to inherit from the same thing twice. (If you can think of workaround for that, that'd also work).
I also haven't tried macros, because I think I know them less than I know metaprogramming, so they might work as a solution.
Any ideas?
Edit: I have a bad solution. I'd still like a meta-programming solution, for the learning, but the bad solution is this:
template<char c1, char c2, char c3> class inheritFromMany
: public key<c1>
, public key<c2>
, public key<c3>
{
};
template<char c1, char c2> class inheritFromMany<c1, c2, 0>
: key<c1>
, key<c2>
{
};
Edit2: Woof, but I forgot a part. I need to pass a variable to the constructor of ''key'' - it's the same in all cases, but it's necessary.
Edit3: Addressing comments:
- I'm not expecting the user to submit the same character more than once. If they did, I would only only want to inherit from that key once - I mean, I guess I didn't mention that because you can't do that? Which is why other, simpler solutions don't work?
- The actual point of this is that key is a wrapper for a signal/slot (channel) behavior. The channel keeps a list of callbacks, which is actually just
virtual key<ch>::callback
. So, inheriting from a key gives you access to that key's channel, lets (or makes) you supply a callback.keyInput<ch1, ch2, ch3,...>
is then a wrapper for that, so you don't have tokey<ch1>, key<ch2>, key<ch3>