0

I have the following code that results in a compilation error trying to bind sort(). I'm trying to redefine std::sort() that is being called in print_sorted() and bound via argument-dependent-lookup.

Does anyone know why the print_sorted<string>() instantiation is unable to bind to the sort() template in declared namespace std? Why the compilation error?

Thans

#include <iostream>
#include <vector>

template<typename T>
void print_sorted(std::vector<T>& v)
{
    sort(v.begin(),v.end());
    for (const auto& x : v)
    std::cout << x << '\n';
}

//#include <algorithm>
namespace std {
    template<class T>
    void sort(typename std::vector<T>::iterator b,
          typename std::vector<T>::iterator e)
    {}
    

#if 0
    void sort(typename std::vector<string>::iterator b,
          typename std::vector<string>::iterator e)
    {
    }
#endif
}

int main(int argc, char *argv[])
{
    std::vector<std::string> v = {"b", "a"};
    print_sorted(v); // sort using std::sort, then print using std::cout
    return 0;
}
// point of instantiation

Compilation:

clang++ -pedantic -Wall -std=c++11 test187.cc && ./a.out
test187.cc:7:5: error: no matching function for call to 'sort'
    sort(v.begin(),v.end());
    ^~~~
test187.cc:31:5: note: in instantiation of function template specialization
      'print_sorted<std::__cxx11::basic_string<char> >' requested here
    print_sorted(v); // sort using std::sort, then print using std::cout
    ^
test187.cc:15:10: note: candidate template ignored: couldn't infer template
      argument 'T'
    void sort(typename std::vector<T>::iterator b,
         ^
1 error generated.
notaorb
  • 1,944
  • 1
  • 8
  • 18
  • 2
    You can't add names to `std` like that, it's UB. – cigien Jul 21 '20 at 04:17
  • 1
    (Setting aside the fact that you should probably experiment with a function not named `sort`, or at least not placed in namespace `std`). In your `sort` template, template parameter `T` cannot be deduced as it only appears in [non-deduced contexts](https://en.cppreference.com/w/cpp/language/template_argument_deduction#Non-deduced_contexts). The only way to call this function is to provide the argument explicitly, as in `sort(...)` – Igor Tandetnik Jul 21 '20 at 04:25
  • You could make it `template std::enable_if_t< std::is_same_v::value_type>::iterator> > sort(It b, It e)` [example](https://godbolt.org/z/fz55Ys). It'll make your overload ambiguous though. – Ted Lyngmo Jul 21 '20 at 04:53
  • See the linked duplicate. In the template `sort` function, `T` is in a _non-deduced context_ because it appears to the left of the scope resolution operator (`::`). Therefore, it will never be deduced by the compiler and must be explicitly given (`sort(v.begin(),v.end())`). – cdhowie Jul 21 '20 at 05:35

0 Answers0