如果存在具有不同参数类型的重载,则在全局命名空间中找不到函数
Function not found from global namespace if there's an overload with different argument types
如果我们在全局命名空间中有一个函数,而在另一个命名空间中有不同参数类型的重载,那么C++编译器似乎没有从全局命名空间中找到该函数。
namespace A
{
class a {
friend void swap(a& first, a& second) { }
};
}
class b {
friend void swap(b& first, b& second) { }
};
namespace C
{
class c {
A::a dataA;
b dataB;
friend void swap(c& first, c& second)
{
swap(first.dataA, second.dataA); // no problem
swap(first.dataB, second.dataB); // VC++12 compiles, C++Builder XE doesn't
}
friend void swap2(c& first, c& second) // no problem with a different name
{
swap(first.dataA, second.dataA);
swap(first.dataB, second.dataB);
}
};
}
C++编译器给出以下错误:
E2357 Reference initialized with 'b', needs lvalue of type 'c'
E2342 Type mismatch in parameter 'first' (wanted 'c &', got 'b')
Visual C++2012编译此文件时没有出现错误。
我已经理解,即使存在具有相同名称和不同参数类型的函数,也应该在全局命名空间中找到该函数。
我是否遗漏了什么,或者这是C++Builder中的一个错误?
对我来说,这看起来像是一个编译器错误。在这两种情况下,ADL都应该在第一种情况下,它在名称空间A
中查找,包括命名空间A
中仅在中声明的名称类a
并找到A::swap
。在第二种情况下,它看起来像全局名称空间(因为这是定义CCD_ 5的地方),包括全局命名空间中仅声明的名称在类别b
中并找到::swap
。
当然,它从非限定名称查找开始,这将在这两种情况下都只能找到C::swap。显然,C++Builder不知怎么的在这种情况下,将::swap
标记为隐藏,并且没有考虑它ADL。然而,在ADL的情况下,全局命名空间并且命名空间A应该被同等对待。
完整规则见§3.4.2。这相当沉重,但像你这样的简单案例,其含义是显而易见的。
与global名称相同的本地作用域的成员总是隐藏全局作用域,所以称之为A::a::swap(first.dataA, second.dataA);
。
相关文章:
- 在命名空间中使用全局命名空间中的函数
- 将好友从模板导出到全局命名空间
- Catalina C++:使用<cmath>标头产生错误:全局命名空间中没有名为 'signbit' 的成员
- 将以"_[a-z0-9]"开头和"using"的标识符导入全局命名空间是否定义良
- 为什么不允许在全局命名空间处阻止范围?
- 运算符<<依赖于参数的查找不在全局命名空间中查找
- 我可以停止 GCC 将标准库名称包含在全局命名空间中吗?
- "uintmax_t":不是"全局命名空间"的成员
- C++项目中的全局命名空间
- 使用 "::member" 引用全局命名空间有什么用吗?
- 在全局命名空间中重载不依赖于用户定义类型的标准定义类型的运算符是否格式正确?
- 使用全局命名空间限定符和指向数据成员的指针
- InitializeCriticalSectionEx 不是 atlwinverapi.h 中全局命名空间的成员
- C++在命名空间中声明与全局命名空间中的函数同名的函数
- 在vs2010中使用iostream时,出现错误C2039:'exit':不是"全局命名空间"的成员
- 是否可以恢复到"default"全局命名空间?
- C++错误代码全局命名空间
- equal()是否默认包含在全局命名空间中
- 前向声明和全局命名空间声明
- C++在全局命名空间中找不到非标准 C 函数