4

Came across the following task in a test:

#include <iostream> using namespace std;

template<typename T> void adl(T) {   cout << "T"; }

struct S { };

template<typename T> void call_adl(T t) {   adl(S());   adl(t); }

void adl(S) {   cout << "S"; }

int main () {   call_adl(S()); }

The question is which functions will be called. There is also an explanation that the name of the function which does not depend on a template argument is resolved at the time of template definition, while the name of those which do depend on a template argument is resolved when a template argument is known. Well, what's the difference between these "times"?

noname7619
  • 3,370
  • 3
  • 21
  • 26

1 Answers1

6

Nice question. It will call the template version first, and the non-template version second. [Live example]

The reason is, as the explanation says, that in this expression:

adl(S());

the name adl is resolved as soon as the parser encounters it. Notice that at this time, the adl(S) function is no yet declared. So the name must resolve to the function template.

The other expression:

adl(t);

is different, because it depends on the the template parameter T (which is the type of t). Therefore, the resolution of the name is postponed until instantiation time, when the argument for T is known. Instantiation happens in main, after the declaration of adl(S). Therefore, this call resolves to the non-template version.

Angew is no longer proud of SO
  • 167,307
  • 17
  • 350
  • 455
  • 1
    Do you mean that it will call the template version first and non-template version second(it looks like there is typo in the first sentence)? – kraskevich Feb 12 '15 at 16:56
  • 1
    Note that msvc doesn't respect the standard here (and call the non-template version twice). – Jarod42 Feb 12 '15 at 17:10
  • I know only the rule that a regular function has precedence before template function specialization. Is there the same for just (not specialized) template? – noname7619 Feb 12 '15 at 17:12
  • @VladimirLenin You can't call a function template; in the end, you always call a function template specialisation - even if it's an implicit one. So the rule you know covers this. – Angew is no longer proud of SO Feb 12 '15 at 17:18