2016-09-21 2 views
10

У меня есть функция шаблона, которая принимает переменное количество аргументов. Поскольку вы не можете заставить аргументы быть определенного типа, я хотел бы, по крайней мере, заставить число аргументов не быть выше, чем определенное количество времени для компиляции (например, 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

можно ограничить аргументы определенным типом. Вы хотите получить ответ? Вам нужно, чтобы аргументы были точно 'T' или что-то конвертируемое в' T'? – bolov

+0

@bolov Да, пожалуйста, это было бы очень полезно! Я буду +1 –

+1

Создано новое сообщение с этим: http://stackoverflow.com/questions/39659127/restrict-variadic-template-arguments/39659128#39659128 – bolov

ответ

20

Для того, чтобы функция не отозвана, когда есть слишком много аргументов, вы можете тяготы функции с 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)... }; 
} 

EDIT: Я добавил ссылку на отправку вместо ссылки на константу, поскольку она может ускорить работу программы и более дружелюбна к типам, не поддающимся копированию.

+3

Это действительно интересный способ использования SFINAE :) – Rakete1111

14

Возможно ли сделать компилятору сообщение об ошибке, если функция шаблона с пакетом параметров имеет количество аргументов, превышающее значение, определенное временем компиляции?

Да, используйте static_assert:

template <class ...Args> 
void setRequestArguments(const Args&... args) 
{ 
    static_assert(sizeof...(args) <= 10, "You can't have more than 10 arguments!"); 
    //Stuff... 
} 
Смежные вопросы