假设我有一个模板
template<typename Bar>
Result foo(const Input& input);
而我想创建一个模板foo()
,该模板将获得许多Bar
模板参数和许多Input
,并将Result
放在一起。
我写了一个带有输入容器的版本:
template<typename Bar>
Result foo(const std::vector<Input>& inputs);
template<typename Bar1, typename Bar2, typename ... Bars>
Result foo(const std::vector<Input>& inputs) {
// calls foo<Bar2, Bars ...>(shorter_inputs);
}
但是,如果输入的长度与模板参数的数量匹配,则上述版本无法在编译时检查。另外,我想要一个只需要输入内容而不需要容器的版本:
foo<Bar1, Bar2>(input1, input2);
// instead of
// foo<Bar1, Bar2>({input1, input2});
我试图写这样的东西
template<typename Bar1, typename Bar2, typename ... Bars>
Result bar(const Input& in1, const Input& in2, const Input& ... inputs)
被编译器拒绝,因为...
仅适用于参数包。是否可以在不使用va_args
的情况下用C ++编写这样的可变参数函数?
答案 0 :(得分:3)
只需使用两个参数包:
EthernetServer ArduinoTcpServer(22);
答案 1 :(得分:1)
不确定要了解什么...
如果Result
和Input
是类型而不是模板参数,并且您希望模板foo()
可以接收多达Input
个对象作为模板参数,则可以从自定义模板参数GetFirst
,以选择可变参数列表中的第一个模板参数
template <typename T0, typename ...>
struct GetFirst
{ using type = T0; };
并按如下所示编写foo()
template <typename ... Bars>
Result foo (typename GetFirst<Input, Bars>::type const & ... is)
{
// something with is...
return {};
}
所以你有
//foo<long, long long>(Input{}, Input{}, Input{}); // compilation error
foo<int, long, long long>(Input{}, Input{}, Input{}); // compiles
//foo<int, long, long long>(Input{}, Input{}); // compilation error
如果您要递归管理单个is...
,则可以按以下方式编写foo()
template <typename, typename ... Bars>
Result foo (Input const & i0,
typename GetFirst<Input, Bars>::type const & ... is)
{
// do something with i0
return foo<Bars...>(is...);
}
,但是您还需要一个基础案例模板foo()
来终止递归;我建议一个foo()
接收一个带有默认值的模板非类型参数(以在列表为空时拦截Bars...
)
template <int = 0>
Result foo ()
{ return {}; }
以下是一个完整的,也许很愚蠢的但编译示例
struct Input { };
struct Result { };
template <typename T0, typename ...>
struct GetFirst
{ using type = T0; };
// ground case
template <int = 0>
Result foo ()
{ return {}; }
// recursive case
template <typename, typename ... Bars>
Result foo (Input const & i0,
typename GetFirst<Input, Bars>::type const & ... is)
{
// do something with i0
return foo<Bars...>(is...);
}
int main()
{
//foo<long, long long>(Input{}, Input{}, Input{}); // compilation error
foo<int, long, long long>(Input{}, Input{}, Input{}); // compiles
//foo<int, long, long long>(Input{}, Input{}); // compilation error
}