【发布时间】:2010-05-28 06:49:56
【问题描述】:
我正在尝试使用 GCC 4.5.0 编译此代码:
#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> >]
Comeau 编译此代码时不会出错。 (4.3.10.1 Beta2,严格的 C++03,没有 C++0x)
这是有效的 C++ 吗?
为什么 GCC 甚至将 std::sort 视为有效的重载?
我做了一些实验,我想我知道为什么 Comeau可能编译这个(但我不知道这个事实):
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。
【问题讨论】:
-
我觉得 Comeau 的行为很奇怪,这意味着他们的
iterator不在std命名空间中,还是我遗漏了什么? -
我用一些你可以玩的代码更新了答案。
标签: c++ templates namespaces g++ overloading