gpt4 book ai didi

c++ - 在这种情况下,为什么 g++ 和 clang 会破坏 namespace 抽象?

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

编译:

struct str {};

namespace a
{
void foo(str s) {}
}
namespace b
{
void foo(str s) {}

void bar(str s) { foo(s); }
}
int main(int, char**)
{
return 0;
}

但这不是(将结构定义移到命名空间 a 内)

namespace a
{
struct str {};

void foo(str s) {}
}
namespace b
{
void foo(a::str s) {}

void bar(a::str s) { foo(s); }
}
int main(int, char**)
{
return 0;
}

我得到的错误是

bad.cpp: In function ‘void b::bar(a::str)’:
bad.cpp:12: error: call of overloaded ‘foo(a::str&)’ is ambiguous
bad.cpp:10: note: candidates are: void b::foo(a::str)
bad.cpp:5: note: void a::foo(a::str)

似乎可以合理预期,因为 a::foo 不在范围内,对 foo 的调用只能引用 b::foo。编译失败是否有充分的理由(如果是,原因是什么),或者(两个主要编译器的)实现是否存在缺陷?

最佳答案

这是因为名称查找的方式,特别是 Argument-Dependent Lookup (ADL) ,作品。在决定哪些函数可能是解析您的调用的候选函数时,编译器将首先在以下位置查找名称:

  1. 函数调用发生的命名空间;
  2. 定义参数类型的命名空间。

如果在这些命名空间中找不到具有该名称的函数,编译器将继续检查进行调用的命名空间的父命名空间。


那么您问题中的示例中发生了什么?

在第一种情况下,str 是在 global 命名空间中定义的,那里没有名为 foo() 的函数。但是,调用发生的命名空间中有一个 (b):因此编译器找到了一个有效名称,名称查找停止,重载解析开始。

但是,只有一个候选函数!所以这里的任务很简单:编译器调用 b::foo()

另一方面,在第二种情况下,str 定义在 a 命名空间中,并且在调用 foo(s) 时,编译器将再次查看进行调用的命名空间 (b) 和定义参数类型 (str) 的命名空间 - 这一次,一个

所以现在有 两个 具有匹配名称的函数来解析调用:输入重载解析! las,这两个函数都同样好(完全匹配,不需要转换)。因此,调用是不明确的。

关于c++ - 在这种情况下,为什么 g++ 和 clang 会破坏 namespace 抽象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15857625/

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