Я пытаюсь скомпилировать этот код с GCC 4.5.0:Странные правила перегрузочные в C++
#include <algorithm>
#include <vector>
template <typename T> void sort(T, T) {}
int main()
{
std::vector<int> v;
sort(v.begin(), v.end());
}
Но это не похоже на работу:
$ g++ -c nm.cpp
nm.cpp: In function ‘int main()’:
nm.cpp:9:28: error: call of overloaded ‘sort(std::vector<int>::iterator, std::vector<int>::iterator)’ is ambiguous
nm.cpp:4:28: note: candidates are: void sort(T, T) [with T = __gnu_cxx::__normal_iterator<int*, std::vector<int> >]
/usr/lib/gcc/i686-pc-linux-gnu/4.5.0/../../../../include/c++/4.5.0/bits/stl_algo.h:5199:69: note: void std::sort(_RAIter, _RAIter) [with _RAIter = __gnu_cxx::__normal_iterator<int*, std::vector<int> >]
Комео компилирует этот код без ошибки. (4.3.10.1 Beta2, строгий C++ 03, нет C++ 0x)
Действительно ли это C++?
Почему GCC даже рассматривает std::sort
как допустимую перегрузку?
Я некоторые эксперименты, и я думаю, я знаю, почему Комео может транслируют это (но я не знаю, что это за факт):
namespace foo {
typedef int* iterator_a;
class iterator_b {};
template <typename T> void bar(T) {}
}
template <typename T> void bar(T) {}
int main()
{
bar(foo::iterator_a()); // this compiles
bar(foo::iterator_b()); // this doesn't
}
Мое предположение о том, что первый вызов разрешается до bar(int*)
, поэтому нет ADL и нет двусмысленности, а второй вызов разрешается до bar(foo::iterator_b)
и тянет foo::bar
(но я не уверен).
Таким образом, GCC, вероятно, использует что-то вроде iterator_b
, в то время как Comeau использует iterator_a
.
Я считаю, что поведение Комо странное, это означает, что их 'итератор' не живет в пространстве имен' std' или мне что-то не хватает? –
Я обновил ответ с помощью кода, с которым вы можете играть. – bucels