12

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?

1

1 Answer 1

15

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.

Not the answer you're looking for? Browse other questions tagged or ask your own question.