gpt4 book ai didi

c++ - C++ 中奇怪的重载规则

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:25:51 25 4
gpt4 key购买 nike

我正在尝试使用 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

最佳答案

您可以明确指定您的 sort通过将名称完全限定为 ::sort 来发挥作用.

模棱两可的过载是由于 argument dependent lookup . C++ 标准没有指定如何 std::vector<*>::iterator应该实现。 gcc 库编写者选择使用模板类型参数为 __gnu_cxx::__normal_iterator 的模板 (std::vector)。 ,它带来了命名空间 std进入关联命名空间的列表。


这是有效的 C++ 吗?

是的,但是两个编译器的行为也符合 C++ 标准。从这个角度来看,ADL 让人非常头疼,直到标准化之后才了解其全部后果。

关于c++ - C++ 中奇怪的重载规则,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2927109/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com