seg-faults についてはわかりませんが、基本関数を呼び出すことはありません。各呼び出しの後にパラメーター リストを縮小する必要があります。
template <typename T>
void fun(T& a) //Base to stop the recursion
{
std::cout << a;
};
template <typename First, typename... Types>
void fun(First arg, Types... args)
{
fun(args...); // recursion on args... (one smaller than what was passed in).
};
基本ケースは参照によってバインドされますが、呼び出しサイトで一時オブジェクトを渡しているため、これはお勧めできません。これはおそらくあなたのセグフォルトの原因です。関数を const 参照または値によって受け入れるように変更します。
また、上記のコードはコンパイルしていないため、パラメーターを 1 つだけ指定して fun を呼び出すと、あいまいな状況になる可能性があることに注意してください。これを修正するには、引数を受け入れないように基本ケースを変更します。
void fun()
{
// base case: no items.
}
template <typename First, typename... Rest>
void fun(First first, Rest... rest)
{
// one or more items (the param pack is allowed to be emoty.)
fun(rest...);
}
または、2 つ以上の引数を受け入れるように再帰的オーバーロードを変更します。
// Exactly one argument.
template <typename T>
void fun(T a)
{
std::cout << a;
};
// Two or more arguments.
template <typename First, typename Second, typename... Rest>
void fun(First first, Second second, Rest... rest)
{
// one or more items (the param pack is allowed to be emoty.)
fun(second, rest...);
}
いずれにせよ、複数の関数テンプレートが拡張の候補となるケースを避けるようにしてください。そうすれば、多くの頭痛の種を回避できます。言い換えれば、すべてのオーバーロードは相互に排他的でなければなりません。