Consider the following code:
#include<vector>
#include<ranges>
#include<algorithm>
//using namespace std;
using namespace std::ranges;
int main()
{
std::vector<int> a = {};
sort(a);
return 0;
}
It's running properly.
Obviously, it called this overload function(functor, strictly speaking):
template<random_access_range _Range,
typename _Comp = ranges::less, typename _Proj = identity>
requires sortable<iterator_t<_Range>, _Comp, _Proj>
constexpr borrowed_iterator_t<_Range>
operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const
{
return (*this)(ranges::begin(__r), ranges::end(__r),
std::move(__comp), std::move(__proj));
}
But after we introducing the namespace std, the function call became ambiguous(got compilation errors):
#include<vector>
#include<ranges>
#include<algorithm>
using namespace std;
using namespace std::ranges;
int main()
{
std::vector<int> a = {};
sort(a);
return 0;
}
In addition to the previous reloads
2045 | inline constexpr __sort_fn sort{};
, there are many other overload functions found in namespace std like:
template<class _ExecutionPolicy, class _RandomAccessIterator> __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void> std::sort(_ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator)
and
template<class _RAIter, class _Compare> constexpr void std::sort(_RAIter, _RAIter, _Compare)
So my questions are:
- The call of sort functor in std::ranges is the best match function, isn't it? Why do these functions later found in std cause ambiguity, rather than being abandoned due to the SFINAE principle?
- If the functions in std are visible for
sort(a)
after we introduced the namespace std, shouldn't it be equally visible in the first code according to the ADL ofa
?