Связано:
Рассмотрим эту пару шаблонов переменной:
template<typename Dummy>
bool All(Param& c) {
return true;
}
template<typename Dummy, Func* f, Func* ...rest>
bool All(Param& c) {
return f(c) && All<Dummy, rest...>(c);
}
Это работаети компилирует.Однако, как написать это без первого параметра шаблона?
Звучит тривиально?Ну вот и я так думал.:-) Давайте рассмотрим некоторые идеи.
Идея № 1:
template<Func* f, Func* ...rest>
bool All(Param& c) {
return f(c) && All<rest...>(c);
}
template<>
bool All(Param& c) {
return true;
}
Не сработает ... Когда я пытался это сделать, я имел в виду специализацию, но со второй мысли этоне так, как это работает.
В исходном примере я создал два разных шаблона перегрузок, сначала приняв 1 параметр шаблона, а затем 2 и более.Никаких двусмысленностей и никакой специализации. Я правильно понял?
Идея № 2:
bool All(Param& c) {
return true;
}
template<Func* f, Func* ...rest>
bool All(Param& c) {
return f(c) && All<rest...>(c);
}
Очевидно, не сработает, All<rest...>
с пустым rest...
не расширитсяк вызову не шаблонной функции.
Идея # 3:
Давайте немного перестроим решение.
template<Func* f>
bool All(Param& c) {
return f(c);
}
template<Func* f, Func* ...rest>
bool All(Param& c) {
return f(c) && All<rest...>(c);
}
Это не пойдет,потому что все (с) было бы неоднозначным.Следовательно, мне нужно иметь случай 0-arg и случай> 0-arg ... Или как насчет случая 1-arg и случая> 1-arg?
Idea # 3.5:
template<Func* f>
bool All(Param& c) {
return f(c);
}
template<Func* f, Func* f2, Func* ...rest>
bool All(Param& c) {
return f(c) && All<f2, rest...>(c);
}
Да, работает, но содержит copypasta (простой в данном случае, но может быть больше!), Поэтому я бы сказал, что это не лучше, чем я начал.Просто еще один обходной путь.
Идея № 4:
Давайте попробуем # 1, но с классами вместо функций.
template<Func* f, Func* ...rest>
struct All {
static bool func(Param& c) {
return f(c) && All<rest...>(c);
}
};
template<>
struct All {
static bool func(Param& c) {
return true;
}
};
Это выглядит многообещающе, так как я могу специализироваться на занятиях.Но эй, что это?
извините, не реализовано: не могу развернуть 'rest ...' в список аргументов фиксированной длины
Разве это не GCC4.4 вещь?Я нахожусь на MinGW GCC 4.6.1 (tdm-1).
В любом случае, должен ли я думать, что я не могу сделать такую элементарную вещь простым способом?Требуется ли использовать обходной путь с дополнительным фиктивным параметром шаблона для выполнения этой задачи?
Или существует простой, правильный вариант для указания регистра с нулевым аргументом , который будет работать?