将可变参数模板函数转换为许多具体函数

时间:2019-07-30 13:37:36

标签: c++ variadic-templates variadic-functions

是否存在编译器标志或技术来强制每次调用具有唯一签名的可变参数函数模板时生成一个非可变函数?

在下面的示例中,编译器创建带有签名int (int, float, double)int (float, double)int (double)的可变参数模板。

#include <iostream>

using namespace std;

template<class IntT, class argsf>
IntT SumArgs(const argsf& firstArg)
{
    return static_cast<IntT>(firstArg);
}

template<class IntT, class argsf, class ...argst>
IntT SumArgs(const argsf& firstArg, const argst&... restArgs)
{
    return static_cast<IntT>(firstArg + SumArgs<IntT>(restArgs...));
}

int main()
{
    cout<<"Sum result: " << SumArgs<int>(1, 2.f, 3.5);
    return 0;
}

前两个保持可变。但是,在某些情况下,可能希望避免可变参数函数的开销,而是为上面列出的每个签名创建唯一的函数定义。有没有办法让编译器做到这一点?另一种选择是编写显式地使用0、1、2 ... n参数的函数版本,以表示一些相当大的n并手动复制代码,但理想情况下,编译器可以为我们完成繁重的工作。

1 个答案:

答案 0 :(得分:2)

C ++ 17引入了折叠表达式,这些折叠表达式(希望如此)恰好是您要寻找的:

template <class R, class... Args>
constexpr R SumArgs(const Args&... args)
{
    return static_cast<R>((args + ...)); // fold expression
}

如果您不想使用可变参数模板,则可以使用initializer_list

template <class R, class T>
constexpr R SumArgs(std::initializer_list<T> args)
{
    return std::accumulate(args.begin(), args.end(), R{});
}