Я пытаюсь написать некоторый код метапрограммирования, такой:
- Наследование от некоторого класса
foo<c1, c2, c3, ...>
приводит к наследованию от key<c1>, key<c2>, key<c3>, ...
- Самый простой подход не совсем работает, потому что вы не можете наследовать от одного и того же пустого класса более одного раза.
- Работа с частью "..." не очень привлекательна (так как это копия-паста), но работает.
Хорошо, вот попытка:
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;
}
Первоначально, хотя я мог использовать Boost :: Mpl, чтобы сделать это, но я, честно говоря, не мог понять, как; Я не мог понять, как вы обойдете list<...>
, не всегда явно зная часть ...
.
Просто делаю:
template<> class key<0> {};
не работает, потому что если у меня есть более одного 0
параметра, я пытаюсь наследовать одно и то же дважды. (Если вы можете придумать обходной путь для этого, это также сработает).
Я также не пробовал макросы, потому что я думаю, что знаю их меньше, чем метапрограммирование, поэтому они могут работать как решение.
Есть идеи?
Редактировать: у меня плохое решение. Я все еще хотел бы решение метапрограммирования, для обучения, но плохое решение - это:
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: Гав, но я забыл часть. Мне нужно передать переменную конструктору '' ключа '' - она одинакова во всех случаях, но это необходимо.
Edit3: адресация комментариев:
- Я не ожидаю, что пользователь отправит один и тот же символ более одного раза. Если бы они это сделали, я бы только хотел наследовать от этого ключа один раз - я имею в виду, я думаю, я не упомянул об этом, потому что вы не можете этого сделать? Вот почему другие, более простые решения не работают?
- Фактически это означает, что ключ является оболочкой для поведения сигнал / слот (канал). Канал хранит список обратных вызовов, который на самом деле составляет всего
virtual key<ch>::callback
. Таким образом, наследование от ключа дает вам доступ к каналу этого ключа, позволяет (или заставляет) предоставить обратный вызов. keyInput<ch1, ch2, ch3,...>
является тогда оберткой для этого, так что вам не нужно key<ch1>, key<ch2>, key<ch3>