Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

aliasing a variadic template function

I have a variadic function like :

void test(int){}

template<typename T,typename...Args>
void test(int& sum,T v,Args... args)
{
    sum+=v;
    test(sum,args...);
}

I want to alias it to something like :

auto sum = test;//error : can not deduce auto from test
int main()
{
    int res=0;
    test(res,4,7);
    std::cout<<res;
}

I tried using std::bind but it doesn't work with variadic functions because it needs placeholders ...

Is it possible to alias a variadic function ?

like image 583
uchar Avatar asked Jun 20 '14 15:06

uchar


2 Answers

In C++1y :

#include <iostream>

void test(int){}

template<typename T,typename...Args>
void test(int& sum,T v,Args... args)
{
  sum+=v;
  test(sum,args...);
}

template<typename T,typename...Args>
decltype(test<T, Args...>)* sum = &(test<T, Args...>);

int     main(void)
{
  int   res = 0;
  sum<int, int>(res, 4, 7);
  std::cout << res << std::endl;
}

Alternatively wrap it in another variadic function and std::forward the arguments :

template<typename T,typename...Args>
void    other(int&sum, T v, Args&&... args)
{
  test(sum, std::move(v), std::forward<Args>(args)...);
}
like image 83
Drax Avatar answered Sep 22 '22 06:09

Drax


What you are trying is not much different from

void test(int)
{
}

void test(double, int)
{
}

auto a = test;

There is no way for the compiler to detect which overload you want to use.

You can be explicit about which test you want to assign to a by:

auto a = (void(*)(int))test;

If you want to add the variadic template version to the mix, you can use:

template<typename T,typename...Args>
void test(int& sum,T v,Args... args)
{
    sum+=v;
    test(sum,args...);
}

auto a = test<int, int, int>;
like image 43
R Sahu Avatar answered Sep 23 '22 06:09

R Sahu