Ограничьте количество параметров в пакете параметров вариационного шаблона
У меня есть функция шаблона, которая принимает переменное количество аргументов. Поскольку вы не можете заставить аргументы быть определенного типа, я хотел бы, по крайней мере, заставить число аргументов не быть выше, чем определенное количество времени компиляции (например, 10).
Можно ли сделать компилятору сообщение об ошибке, если функция шаблона с пакетом параметров имеет количество аргументов, превышающее значение, определяемое временем компиляции?
template <class ...Args>
void setRequestArguments(const Args&... args)
{
const std::vector<QGenericArgument> vec = { args... };
qDebug() << sizeof...(args);
// Do stuff...
// for (unsigned i = 0; i < vec.size(); ++i) {
// qDebug() << vec[i].name();
// }
}
Я хочу использовать его для универсального контейнера для всех аргументов в QMetaObject::invokeMethod
обертке.
Ответы
Ответ 1
Чтобы сделать функцию не вызываемой, когда слишком много аргументов, вы можете ограничить функцию с помощью sfinae. Таким образом, если есть другая перегрузка, которая принимает больше аргументов, компилятор сможет выбрать правильную перегрузку.
Простой std::enable_if
с условием будет достаточно:
template <class ...Args, std::enable_if_t<(sizeof...(Args) <= 10)>* = nullptr>
void setRequestArguments(Args&&... args)
{
const std::vector<QGenericArgument> vec = { std::forward<Args>(args)... };
}
Для удобства чтения вы можете поместить ограничение в возвращаемый тип возвращаемой функции:
template <class ...Args>
auto setRequestArguments(Args&&... args) -> std::enable_if_t<(sizeof...(args) <= 10)>
{
const std::vector<QGenericArgument> vec = { std::forward<Args>(args)... };
}
РЕДАКТИРОВАТЬ: Я добавил ссылку на отправку вместо ссылки на константу, поскольку она может ускорить работу программы и более дружелюбна к нескольким типам.
Ответ 2
Можно ли сделать компилятору сообщение об ошибке, если функция шаблона с пакетом параметров имеет количество аргументов, превышающее значение, определенное временем компиляции?
Да, используйте static_assert
:
template <class ...Args>
void setRequestArguments(const Args&... args)
{
static_assert(sizeof...(args) <= 10, "You can't have more than 10 arguments!");
//Stuff...
}