简体   繁体   English

C ++中的命名空间冲突

[英]Namespace Clashing in C++

I cannot understand why this piece of code does not compile: 我无法理解为什么这段代码不能编译:

namespace A {
        class F {};             // line 2
        class H : public F {};
}

namespace B {
        void F(A::H x);         // line 7
        void G(A::H x) {
                F(x);           // line 9
        }
}

I am using gcc 4.3.3 , and the error is: 我使用的是gcc 4.3.3 ,错误是:

s3.cpp: In function ‘void B::G(A::H)’:
s3.cpp:2: error: ‘class A::F’ is not a function,
s3.cpp:7: error:   conflict with ‘void B::F(A::H)’
s3.cpp:9: error:   in call to ‘F’

I think that because in line 9 there is no namespace prefix, F(x) should definitively mean only B::F(x) . 我认为因为在第9行没有名称空间前缀, F(x)应该明确地仅表示B::F(x) The compiler tries to cast x into its own superclass. 编译器尝试将x转换为自己的超类。 In my understanding it should not. 根据我的理解,它不应该。 Why does it do that? 为什么这样做?

That's because compiler will search function in the same namespace its arguments from. 那是因为编译器将在其参数的相同名称空间中搜索函数。 Compiler found there A::F identifier but it is not a function. 编译器发现有A::F标识符,但它不是函数。 In result you'll get the error. 结果你会得到错误。

It is standard behaviour as far as I can remember. 据我所知,这是标准行为。

3.4.2 Argument-dependent name lookup When an unqualified name is used as the postfix-expression in a function call (5.2.2), other namespaces not considered during the usual unqualified lookup (3.4.1) may be searched, and namespace-scope friend function declarations (11.4) not otherwise visible may be found. 3.4.2依赖于参数的名称查找当在函数调用(5.2.2)中使用非限定名称作为后缀表达式时,可以搜索在通常的非限定查找(3.4.1)中未考虑的其他名称空间,并且可以搜索名称空间 -可以找到范围友元函数声明(11.4),否则不可见。 These modifications to the search depend on the types of the arguments (and for template template arguments, the namespace of the template argument). 对搜索的这些修改取决于参数的类型(以及模板模板参数,模板参数的命名空间)。

For each argument type T in the function call, there is a set of zero or more associated namespaces and a set of zero or more associated classes to be considered. 对于函数调用中的每个参数类型T,存在一组零个或多个关联的命名空间以及要考虑的一组零个或多个关联的类。 The sets of namespaces and classes is determined entirely by the types of the function arguments (and the namespace of any template template argument). 命名空间和类的集合完全由函数参数的类型(以及任何模板模板参数的命名空间)决定。 Typedef names and using-declarations used to specify the types do not contribute to this set. 用于指定类型的Typedef名称和using-declarations对此集合没有贡献。 The sets of namespaces and classes are determined in the following way... 命名空间和类的集合按以下方式确定......

This rule allows you to write the following code: 此规则允许您编写以下代码:

std::vector<int> x;
// adding some data to x
//...

// now sort it
sort( x.begin(), x.end() ); // no need to write std::sort

And finally: Because of Core Issue 218 some compilers would compile the code in question without any errors. 最后:由于核心问题218,一些编译器会编译有问题的代码而没有任何错误。

Have you tried using other compilers yet? 你尝试过使用其他编译器吗? There is a gcc bug report here which is suspended (whatever that means). 这里有一个gcc bug报告暂停(无论这意味着什么)。

EDIT: After some research, I found this more official bug . 编辑:经过一些研究,我发现这个更正式的bug

Very strange, I copied and pasted directly to VS 2005 and I get an error, which I expected: 很奇怪,我直接复制并粘贴到VS 2005,我得到一个错误,我期望:

Error 1 error LNK2001: unresolved external symbol "void __cdecl B::F(class A::H)" 错误1错误LNK2001:未解析的外部符号“void __cdecl B :: F(A类:: H)”

Because we haven't actually defined F(x) in namespace B... not sure why Gcc is giving this error. 因为我们实际上没有在命名空间B中定义F(x)...不确定为什么Gcc会给出这个错误。

I just tried compiling it on Visual Studio 2005 and it worked fine. 我只是尝试在Visual Studio 2005上编译它,它工作正常。 I wonder if it's a broken implementation of Argument Dependent Lookup where the namespace from the arguments was accidentally brought in? 我想知道它是否是Argument Dependent Lookup的破坏实现,其中参数的命名空间被意外引入?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM