Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does this template type deduction and overload resolution work?

Code #1

#include <iterator>
#include <algorithm>
#include <iostream>
#include <vector>

template <typename container>
void sort(typename container::iterator beginning,
          typename container::iterator end)
{
    std::cout << "calling custom sorting function\n";
}

int main()
{
    std::vector<int> v{1, 2, 3};
    sort(v.begin(), v.end());
}

Wandbox.

Code description

It is gonna call the std::sort function, which is found by ADL. Though the code below:

Code #2

#include <iterator>
#include <algorithm>
#include <iostream>
#include <vector>

template <typename Iterator>
void sort(Iterator beginning,
          Iterator end)
{
    std::cout << "calling custom sorting function\n";
}

int main()
{
    std::vector<int> v{1, 2, 3};
    sort(v.begin(), v.end());
}

Wandbox.

Causes ambiguous overload error. So I have two questions:

Questions

  1. How container was deduced in code #1?

    From what I know, type deduction during template instantiation cannot backtrack through member types to find the enclosing one (std::vector<int> in this case).

  2. Even if it could backtrack, why did it compile without causing ambiguous overload error?

like image 854
Incomputable Avatar asked Apr 10 '18 08:04

Incomputable


1 Answers

How container was deduced in code #1?

It can't be deduced during template argument deduction because of non-deduced context,

1) The nested-name-specifier (everything to the left of the scope resolution operator ::) of a type that was specified using a qualified-id:

That means your sort won't be considered for overload resolution at all, then std::sort is called without ambiguity.

Code #2 doesn't have such issue, both your sort and std::sort are valid candidates then leads to ambiguous overloading error.

like image 138
songyuanyao Avatar answered Nov 02 '22 10:11

songyuanyao