简体   繁体   中英

Variadic function and variadic template overloading lookup

I have a function with 2 overloaded arguments

template<typename... Args>
void f(Args&&...) {
    cout << "Args..." << endl;
}
 
void f(...) {
    cout << "..." << endl;
}

Can someone explain how does the lookup work? In my opinion, purpose of each function is the same (except first one is c++ style and second is c style). When I call function with arguments despite their types f(5, "hello") or f(5, 10) it is always variadic template (first overload), but when I call function without arguments f() it is always variadic function (second overload). Is there a strong rule which compiler follows to choose the right function and what is the logic behind it?

Yes there are many rules around this in C++.

When the compiler encounters a call like f(5, 10) , first a list of viable candidates is synthesized, which involves instantiation of function templates (which involves deduction of template arguments).

Then, if the list has more than one candidate, overload resolution is performed.

Some key overload ranking rules are:

  • A better match (the one with least amount of implicit conversions) is always preferred.

    • A standard conversion is better than a user-defined conversion, which is better than the ellipsis.
  • When there's no better match, the non-template version is preferred.

So in case of f(5, 10) we get

  • f<int,int>(int,int) - requires 0 conversions,
  • f(...) - requires 2 ellipsis "conversions".

The first one requires less conversions, so it wins.

In case of f() we get

  • f<>() - requires 0 conversions,
  • f(...) - requires 0 conversions.

An ambiguity, but the first one is a template, so the non-template f(...) is selected.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM