c++ - This case of template function overloading eludes my understanding -


#include <iostream>  template<typename t> struct identity {     typedef t type; };  template<typename t> void bar(t) { std::cout << "a" << std::endl; } template<typename t> void bar(typename identity<t>::type) { std::cout << "b" << std::endl; }  int main () {     bar(5); // prints "a" because of template deduction rules     bar<int>(5); // prints "b" because of ...?      return exit_success; } 

i expected bar<int>(5) result in ambiguity, @ least. crazy rule template function overload resolution involved here?

once our candidate functions set (both bars), , whittle down viable functions (still both bars) have determine best viable function. if there more one, ambiguity error. steps take determine best 1 laid out in [over.match.best]:

[a] viable function f1 defined better function viable function f2 if arguments i, icsi(f1) not worse conversion sequence icsi(f2), , then
— argument j, icsj(f1) better conversion sequence icsj(f2), or, if not that,

both functions take argument of type int, both conversion sequences identical. continue.

— context initialization user-defined conversion [...]

does not apply.

— context initialization conversion function direct reference binding (13.3.1.6) of reference function type, [...]

does not apply.

— f1 not function template specialization , f2 function template specialization, or, if not that,

both bar<int>s function template specializations. move onto last bullet point to determine best viable function.

— f1 , f2 function template specializations, , function template f1 more specialized template f2 according partial ordering rules described in 14.5.6.2.

the partial ordering rules boil down synthesizing new unique types arguments of both bar overloads , performing template deduction on other overload.

consider "b" overload first. synthesize type typename identity<unique1>::type , attempt perform template deduction against t. succeeds. simplest cast of template deduction there is.

next, consider "a" overload. synthesize type unique2 , attempt perform template deduction against typename identity<t>::type. fails! non-deduced context - no deduction can succeed.

since template type deduction succeeds in single direction, bar(typename identity<t>::type) overload considered more specialized, , chosen best viable candidate.


bogdan presents interesting case looking @ partial ordering. consider instead comparing:

template <typename t> void bar(t, t); // "c" template <typename t> void bar(t, typename identity<t>::type ); // "d"  bar(5,5); bar<int>(5, 5); 

again, both candidates viable (this time without explicitly specifying t) @ partial ordering rule.

for "c" overload, synthesize arguments of type uniquec, uniquec , attempt perform deduction against t, typename identity<t>::type. succeeds (with t == uniquec). "c" @ least specialized "d".

for "d" overload, synthesize arguments of type uniqued, typename identity<uniqued>::type , attempt perform deduction against t, t. fails! arguments of different types! "d" not @ least specialized "c".

thus, "c" overload called.


Comments

Popular posts from this blog

javascript - Using jquery append to add option values into a select element not working -

Android soft keyboard reverts to default keyboard on orientation change -

Rendering JButton to get the JCheckBox behavior in a JTable by using images does not update my table -