使用参数包时,我觉得有点不舒服。我有一个功能
template <class ... Args>
void f( int x, Args ... args, int y )
{}
当然使用它就像这样有效:
f( 5, 3 );
我想知道为什么以下调用失败:
f( 5, 3.f, 3 );
这似乎是对我的直接使用参数包,但根据编译器Args
未扩展。
当然,我可以轻松地将f
替换为:
template <class ... Args>
void f( int x, Args ... args )
{
static_assert( sizeof...( args ) >= 1, ... );
extract y from args ...
}
问题:
为什么我不能使用这样的参数包?似乎编译器可以轻松创建替换代码。或者上面的替换f()
是否存在任何问题?
如果参数的顺序对我很重要,那么处理此问题的最佳方法是什么? (考虑std::transform
任意数量的输入迭代器。)
为什么在上述情况下不禁止使用参数包?我认为,这是因为它们可以明确地扩展,例如, f<float>( 5, 3.f, 3 )
答案 0 :(得分:2)
为什么我不能使用这样的参数包?似乎编译器可以轻松创建替换代码。或者上面替换f()有什么问题吗?
在这种特殊情况下可能很容易,也可能不在其他情况下。真正的答案是标准指定了行为,标准没有指定任何转换......通常很少。
我会注意到您的转换不适用于SFINAE ,因为static_assert
是硬错误,因此我很高兴转换未执行。 (提示:如果使用f
的单参数版本重载了float
会怎样?f(1)
会选择是否进行转换?) < / p>
如果参数的顺序对我来说真的很重要,最好的方法是什么? (考虑
std::transform
任意数量的输入迭代器。)
明确指定模板包参数。
为什么在上述情况下不禁止使用参数包?我认为,这是因为它们可以明确地扩展,例如, f(5,3.f,3)?
我认为你的假设是正确的;如果明确指定,则按预期工作。
答案 1 :(得分:1)
您可以使用其他非可变参数模板参数,但只有在将这些非可变参数分配给非可变参数后,剩余部分才能构成可变参数的参数包。因此,您必须将参数列表末尾的int y
移动到可变参数之前。类似的东西:
template <class... Args>
void f(int x, int y, Args... args)
{}