Сообщение Re[5]: Помогите с вариадиками от 09.01.2018 18:14
Изменено 09.01.2018 18:22 watchmaker
Re[5]: Помогите с вариадиками
Здравствуйте, SaZ, Вы писали:
SaZ> А можете пояснить про typename T = void и почему это помогло?
Это не самая важная часть: можно и без этого.
Указания параметра по умолчанию =void используется просто чтобы задать условие окончания через специализацию (а она для функций возможна только полная).
Чаще, конечно, окончание рекурсии делается через подсчёт параметров и ту же перегрузку. Но тут у тебя все функции имеют ровно один и тот же список аргументов (const Table& table), и для них этот способ закрыт.
Хотя можно это обойти, если ввести в сигнатуру функции эти типы, добавив, например, фиктивный аргумент.
Тогда у всех функций будут разные сигнатуры и перегрузка будет работать:
Тут просто передаётся нулевой указатель (оптимизатор его выбросит потом) на кортеж, параметры которого и являются тем списком классов, который осталось проверить.
SaZ> А можете пояснить про typename T = void и почему это помогло?
Это не самая важная часть: можно и без этого.
Указания параметра по умолчанию =void используется просто чтобы задать условие окончания через специализацию (а она для функций возможна только полная).
Чаще, конечно, окончание рекурсии делается через подсчёт параметров и ту же перегрузку. Но тут у тебя все функции имеют ровно один и тот же список аргументов (const Table& table), и для них этот способ закрыт.
Хотя можно это обойти, если ввести в сигнатуру функции эти типы, добавив, например, фиктивный аргумент.
Тогда у всех функций будут разные сигнатуры и перегрузка будет работать:
bool ValidateTuple(const Table& table, std::tuple<>*) {
return false;
}
template <typename Head, typename ...Tail>
bool ValidateTuple(const Table& table, std::tuple<Head*, Tail*...>*)
{
if (Validate_1<Head>(table))
return true;
return ValidateTuple(table, static_cast<std::tuple<Tail*...>*>(nullptr));
}
template <typename ...Tables>
bool Validate(const Table& table) {
return ValidateTuple(table, static_cast<std::tuple<Tables*...>*>(nullptr));
}
Тут просто передаётся нулевой указатель (оптимизатор его выбросит потом) на кортеж, параметры которого и являются тем списком классов, который осталось проверить.
Re[5]: Помогите с вариадиками
Здравствуйте, SaZ, Вы писали:
SaZ> А можете пояснить про typename T = void и почему это помогло?
Это не самая важная часть: можно и без этого.
Указания параметра по умолчанию =void используется просто чтобы задать условие окончания через специализацию (а она для функций возможна только полная).
Чаще, конечно, окончание рекурсии делается через подсчёт параметров и ту же перегрузку. Но тут у тебя все функции имеют ровно один и тот же список аргументов (const Table& table), и для них этот способ закрыт.
Хотя можно это обойти, если ввести в сигнатуру функции эти типы, добавив, например, фиктивный аргумент.
Тогда у всех функций будут разные сигнатуры и перегрузка будет работать:
Тут просто передаётся нулевой указатель (оптимизатор его выбросит потом) на кортеж, параметры которого и являются тем списком классов, который осталось проверить.
Upd: Этот код — просто демонстрация, я не говорю, что так нужно писать :)
SaZ> А можете пояснить про typename T = void и почему это помогло?
Это не самая важная часть: можно и без этого.
Указания параметра по умолчанию =void используется просто чтобы задать условие окончания через специализацию (а она для функций возможна только полная).
Чаще, конечно, окончание рекурсии делается через подсчёт параметров и ту же перегрузку. Но тут у тебя все функции имеют ровно один и тот же список аргументов (const Table& table), и для них этот способ закрыт.
Хотя можно это обойти, если ввести в сигнатуру функции эти типы, добавив, например, фиктивный аргумент.
Тогда у всех функций будут разные сигнатуры и перегрузка будет работать:
bool ValidateTuple(const Table& table, std::tuple<>*) {
return false;
}
template <typename Head, typename ...Tail>
bool ValidateTuple(const Table& table, std::tuple<Head*, Tail*...>*)
{
if (Validate_1<Head>(table))
return true;
return ValidateTuple(table, static_cast<std::tuple<Tail*...>*>(nullptr));
}
template <typename ...Tables>
bool Validate(const Table& table) {
return ValidateTuple(table, static_cast<std::tuple<Tables*...>*>(nullptr));
}
Тут просто передаётся нулевой указатель (оптимизатор его выбросит потом) на кортеж, параметры которого и являются тем списком классов, который осталось проверить.
Upd: Этот код — просто демонстрация, я не говорю, что так нужно писать :)