gpt4 book ai didi

c++ - 为什么编译器会在这里提示函数歧义?

转载 作者:行者123 更新时间:2023-11-30 02:04:19 25 4
gpt4 key购买 nike

我正在尝试运行“Accelerated C++”(A. Koenig、B. Moo)一书中的一些示例代码 (§8.2.2):

#include <iostream>
#include <vector>

using std::cout;
using std::endl;
using std::vector;

template <class In, class X>
In find(In begin, In end, const X &x)
{
while (begin != end && *begin != x) {
++begin;
}

return begin;
}

int main()
{
vector<int> v;

v.push_back(5);
v.push_back(32);
v.push_back(42);
v.push_back(7);

cout << *find(v.begin(), v.end(), 42) << endl;

return 0;
}

find函数在书中是这样出现的;我自己编写的 main 函数。

clang++ 和 g++ 都不会编译它。他们似乎在提示我的 find 函数引入了与 std::find 的歧义。但是,我从未在代码中使用 using namespace::std;using std::find;,因此甚至不应该允许编译器使用 std::find 如果它被包含。这是怎么回事?

最佳答案

我认为您被“Koenig 查询”绊倒了(是的,同一个 Koenig,所以您认为他会发现问题),又名“ADL”。

假设通过间接包含,<algorithm>已经拉进来了。

如果std::vector<int>::iterator (参数的类型)是命名空间 std 中的一个类, 然后 std::find与您的调用匹配,即使您从未“使用”过它,因此该调用是不明确的。

如果std::vector<int>::iteratorint* , 然后 std::find不是候选人,并且调用没有歧义。

这两种方式都是 std::vector 的有效实现,它也是实现定义的,无论是 <iostream><vector>包括 <algorithm> .因此,您的代码不可移植,但实现几乎无法诊断可移植性问题,除非代码在该实现上实际失败。

在更典型的 ADL 案例中,关联命名空间中的函数或函数模板比​​调用者驻留或“使用”的命名空间中的函数或函数模板更适合(更具体),因此避免了歧义。但是你的全局findstd::find 基本相同,所以这不适用。

http://ideone.com/Cskur :

#include <iostream>

namespace foo {
struct Foo {};

/* same as the one we'll define later */
template <typename T>
void func(T) {
std::cout << "namespace function template\n";
}
/* this would be a better match
void func(Foo) {
std::cout << "namespace function\n";
}
*/
}

template <typename T>
void func(T) {
std::cout << "global function template\n";
}

int main() {
foo::Foo f;
func(f);
}

结果:

prog.cpp:19: error: call of overloaded ‘func(foo::Foo&)’ is ambiguous

结论:使用来自 std 的名称有些危险,甚至在其他命名空间中。

或者如果您愿意:从 std 定义名称在其他 namespace 中可能意味着调用者需要小心。区别主要在于错误发生时由谁来修复。

关于c++ - 为什么编译器会在这里提示函数歧义?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10825837/

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