6

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 ?

uchar
  • 2,552
  • 4
  • 29
  • 50
  • 3
    `auto sum = [](auto&&... pp) { return test(std::forward(pp)...); };` or something like that. It's not a true alias, though; for example, you can't use `auto x = &sum;`. – dyp Jun 20 '14 at 15:10

3 Answers3

4

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)...);
}
dyp
  • 38,334
  • 13
  • 112
  • 177
Drax
  • 12,682
  • 7
  • 45
  • 85
  • 1
    Interesting, but I doubt type deduction will work for this "alias". – dyp Jun 20 '14 at 16:44
  • @dyp Currently it does not with the usual compilers, but maybe some day not so far :) – Drax Jun 20 '14 at 16:45
  • Hmm I doubt the syntax for *variable templates* will support this; since the template defined has no patterns to match with the arguments of the function call. Consider specializations of the variable template. Only in very restricted contexts could a variable template be seen as an alias, and the compiler had to look "through" this layer of abstraction. – dyp Jun 20 '14 at 16:50
  • `std::forward(v)` is not necessary since `T v` is not a universal reference. `std::move(v)` is sufficient. – dyp Jun 20 '14 at 16:53
  • @dyp updated :) As for the deduction i agree with you although an obvious case to try automatic deduction is when an operator() is called on a variable template which means it is most likely a callable which might be totally deduced by that call. But i'm not a compiler writer so this is total speculation ^^ – Drax Jun 20 '14 at 16:58
1

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>;
R Sahu
  • 204,454
  • 14
  • 159
  • 270
  • BTW for this case, if he wanted `test(double, int)`, he could do this: http://ideone.com/KFJnjh – yizzlez Jun 20 '14 at 15:18
  • I know that , I was looking for a way for alising variadic function. @dyp solutions seems working with gcc 4.9 ,http://coliru.stacked-crooked.com/a/d3aabbd801efe463 – uchar Jun 20 '14 at 15:20
  • It is not answering the question.BTW `auto a = test;` does not works : http://coliru.stacked-crooked.com/a/4c19105de2b3d597 – uchar Jun 20 '14 at 15:27
  • For three arguments, you use `auto a = test` – yizzlez Jun 20 '14 at 15:45
  • @awesomeyi I need something that works in general case, my question was just simplified version of my code,I can't use auto for all of the possible ways ! – uchar Jun 20 '14 at 15:47
0

This is not aliasing.auto a = test tries to declare a variable a with the same type as test and make them equal. Since test isn't a single function, but a function template (and on the top of that you can even overload functions), the compiler can't decide on what the type of a should be.

To alias a template, or as a matter of fact any symbol, you can use the using keyword.

using a = test;

Edit: sorry this one only works for types not functions.

Evan Dark
  • 1,311
  • 7
  • 7