Re[5]: Помогите с вариадиками
От: watchmaker  
Дата: 09.01.18 18:14
Оценка: 6 (1)
Здравствуйте, SaZ, Вы писали:

SaZ> А можете пояснить про typename T = void и почему это помогло?


Это не самая важная часть: можно и без этого.
Указания параметра по умолчанию =void используется просто чтобы задать условие окончания через специализацию (а она для функций возможна только полная).

Чаще, конечно, окончание рекурсии делается через подсчёт параметров и ту же перегрузку. Но тут у тебя все функции имеют ровно один и тот же список аргументов (const Table& table), и для них этот способ закрыт.

Хотя можно это обойти, если ввести в сигнатуру функции эти типы, добавив, например, фиктивный аргумент.
Тогда у всех функций будут разные сигнатуры и перегрузка будет работать:
template <typename... Types>
using TupleTypeList = std::tuple<Types*...>*; // сделаем список на основе существующего std::tuple, чтобы не писать для примера свой класс

bool ValidateTuple(const Table& table, TupleTypeList<>) { // перегрузка для пустого списка типов
    return false;
}

template <typename Head, typename ...Tail>
bool ValidateTuple(const Table& table, TupleTypeList<Head, Tail...>)  // разбор общего случая с непустым списком типов
{
    if (Validate_1<Head>(table))
      return true;
    return ValidateTuple(table, TupleTypeList<Tail...>{});
}

template <typename ...Tables> 
bool Validate(const Table& table) {
    return ValidateTuple(table, TupleTypeList<Tables...>{});
}

Тут просто передаётся нулевой указатель (оптимизатор его выбросит потом) на кортеж, параметры которого и являются тем списком классов, который осталось проверить.

Upd: Этот код — просто демонстрация, я не говорю, что так нужно писать :)
Отредактировано 10.01.2018 13:11 watchmaker . Предыдущая версия . Еще …
Отредактировано 09.01.2018 18:22 watchmaker . Предыдущая версия .
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.