Вы не можете использовать int...
в качестве пакета параметров, и поэтому это не работает. Кроме того, чтобы отделить источник от определения, вы должны полностью указать шаблон, поэтому int...
не будет работать, даже если этот синтаксис был разрешен.
Способы обойти это.
1. Заставьте Function
принять список инициализаторов.
Мы можем написать функцию так, чтобы она принимала список инициализаторов int
s:
#include <initializer_list>
class Foo {
public:
void Function(int t1, std::initializer_list<int> t2);
};
void Foo::Function(int t1, std::initializer_list<int> t2) {
for(int i : t2) {
// stuff
}
}
Теперь вы можете довольно просто позвонить на Function
, и он даже не настроен:
Foo f;
f.Function(10, {1, 2, 3, 4, 5});
Если есть другие места, где вы используете шаблоны, вы можете развернуть пакет параметров непосредственно в списке инициализатора:
template<class... Args>
void invoke_foo(Foo& f, int first, Args... rest) {
f.Function(first, {rest...});
}
2. Используйте SFINAE для отключения всех перегрузок не-int. Мы можем отключить все перегрузки Foo::Function
, которые не только принимают int
s
#include <type_traits>
class Foo {
public:
// Requires C++17 for std::conjunction
// You could write your own std::conjunction too if you'd prefer
template<class... Args>
auto Function(int t1, Args... t2)
-> std::enable_if_t<std::conjunction<std::is_same<Args, int>...>::value>
{
// stuff
}
};
Недостатком этого является то, что нецелые значения не будут автоматически преобразованы в int
.