#include <stdio.h>
#include <cstddef>
#include <cstring>
namespace /*namespace name generated by compiler*/
{
struct BB{};
}
struct AA{};
namespace my
{
inline void * memcpy(void*, const void*, std::size_t)
{
puts("CUSTOM IMPLEMENTATION");
return 0;
}
}
namespace my
{
void func()
{
AA a;
memcpy(&a, &a, sizeof(a)); // ambigious call for g++4.7 - g++6.2
BB b;
memcpy(&b, &b, sizeof(b)); // unambigious call
}
}
int main(int, char **)
{
my::func();
return 0;
}
为什么 memcpy 在这里打电话?
请看一下变量&#34; i&#34;在ANSI ISO IEC 14882,C ++ 2003,3.4.1,(6)(第30页)中。它&#34;证明&#34;在这样的建筑中没有任何野心。
namespace A {
namespace N {
void f();
}
}
void A::N::f() {
i = 5;
// The following scopes are searched for a declaration of i:
// 1) outermost block scope of A::N::f, before the use of i
// 2) scope of namespace N
// 3) scope of namespace A
// 4) global scope, before the definition of A::N::f
}
GCC中是否违反了不合格的查询规则或者我不明白?
答案 0 :(得分:6)
要查找的名称是功能名称;特殊here规则在此处生效。 (请注意,ADL是函数名称argument-dependent lookup的一部分。)
除了通常的非限定名称查找所考虑的范围和名称空间之外,还会在其参数的名称空间中查找这些函数名称。
首先,您包含string.h
,它在全局命名空间中引入了名称memcpy
。
AA
在全局命名空间中声明;然后当你调用memcpy(&a, &a, sizeof(a));
时,也会考虑声明AA
的命名空间(即全局命名空间),并且命名空间memcpy
中声明的my
将由通常unqualified name lookup,所以调用是模棱两可的。
另一方面,BB
没有这样的问题,因为它没有在全局命名空间中声明(然后ADL不会对它生效)。