Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ambiguous call when recursively calling variadic template function overload

Consider this piece of code:

template<typename FirstArg>
void foo()
{
}

template<typename FirstArg, typename... RestOfArgs>
void foo()
{
    foo<RestOfArgs...>();
}

int main()
{
    foo<int, int, int>();
    return 0;
}

It does not compile due to ambiguous call foo<RestOfArgs...>(); when RestOfArgs has only one element ({int}).

But this compiles without error:

template<typename FirstArg>
void foo(FirstArg x)
{
}

template<typename FirstArg, typename... RestOfArgs>
void foo(FirstArg x, RestOfArgs... y)
{
    foo(y...);
}

int main()
{
    foo<int, int, int>(5, 6, 7);
    return 0;
}

Why is there ambiguity in the first case?

Why is there no ambiguity in the second case?

like image 208
rubix_addict Avatar asked Feb 06 '17 08:02

rubix_addict


People also ask

What is the error call of overloaded Char is ambiguous?

prog.cpp:25:11: error: call of overloaded ‘test (char)’ is ambiguous When there is no exact type match, the compiler looks for the closest match. The closest match for “test (‘a’);” will be “void test (int a)”, since it is not present, void test (double d) and void (float f)will cause ambiguity.

What is ambiguity in function overloading?

In Function overloading, sometimes a situation can occur when the compiler is unable to choose between two correctly overloaded functions. This situation is said to be ambiguous. Ambiguous statements are error-generating statements and the programs containing ambiguity will not compile. Automatic type conversions are the main cause of ambiguity.

What is a variadic template?

This means that all functions that have 1 or more arguments are matched to the variadic template and all functions that with no argument are matched to the empty function. This article is contributed by MAZHAR IMAM KHAN.

What is ambiguous statement in C++?

Ambiguous statements are error-generating statements and the programs containing ambiguity will not compile. Automatic type conversions are the main cause of ambiguity. In C++, the type of argument that is used to call the function is converted into the type of parameters defined by the function.


1 Answers

The answer by @ZangMingJie answers the difference in behavior your are observing in your code.

I found it easier to understand the name resolution with the following change:

template<typename FirstArg>
void foo()
{
    printf("1\n");
}

template<typename FirstArg, typename SecondArg, typename... RestOfArgs>
void foo()
{
    printf("2\n");
    foo<SecondArg, RestOfArgs...>();
}

int main()
{
    foo<int, int, int>();
    return 0;
}

When there are two or more template parameters are used, the second function gets invoked. When there is one template parameters, the first function gets invoked.

like image 166
R Sahu Avatar answered Nov 03 '22 18:11

R Sahu