简体   繁体   English

此代码如何引起NS1 :: format和NS3 :: format之间的歧义?

[英]How can this code cause ambiguity between NS1::format and NS3::format?

Is format imported because it is using imported Object class? 是否由于使用导入的Object类而导入了格式? But with the same logic, a class is not imported if it uses imported Object class. 但是按照相同的逻辑,如果一个类使用导入的Object类,则不会导入该类。

namespace NS1  {
    class Object { /* ... */ };
    int format(const Object&) { std::cout << "NS1"; }
    namespace NS2  {
        class Object { /* ... */ };
        int format(const Object&) { std::cout << "NS2"; }
    }
}

namespace NS3  {
    using NS1::Object;
    int format(const Object&) { std::cout << "NS3"; }
}

namespace  {  using namespace NS3;  }

void fun(Object b, int i)  {  int i1 = format(b);  }

int main()  {
    Object b;
    fun(b, 0);
}

Let's have a look at the error message that GCC produces: 让我们看一下GCC产生的错误消息:

test.cpp: In function ‘void fun(NS1::Object, int)’:
test.cpp:19:48: error: call of overloaded ‘format(NS1::Object&)’ is ambiguous
 void fun(Object b, int i)  {  int i1 = format(b);  }
                                                ^
test.cpp:19:48: note: candidates are:
test.cpp:14:5: note: int NS3::format(const NS1::Object&)
 int format(const Object&) { std::cout << "NS3"; }
     ^
test.cpp:5:5: note: int NS1::format(const NS1::Object&)
 int format(const Object&) { std::cout << "NS1"; }
     ^

The ambiguity arises because of argument-dependent lookup : 由于依赖参数的查找而产生歧义:

Argument-dependent lookup, also known as ADL, or Koenig lookup, is the set of rules for looking up the unqualified function names in function-call expressions, including implicit function calls to overloaded operators. 依赖于参数的查找(也称为ADL或Koenig查找)是用于在函数调用表达式中查找不合格函数名称的规则集,包括对重载运算符的隐式函数调用。 These function names are looked up in the namespaces of their arguments in addition to the scopes and namespaces considered by the usual unqualified name lookup. 除了通常的非限定名称查找所考虑的范围和名称空间之外,还在其参数的名称空间中查找这些函数名称。

In your case, you are trying to call format(b) where b is a NS1::Object . 在您的情况下,您尝试调用format(b) ,其中bNS1::Object

  • The function int NS3::format(const NS1::Object&) is considered because you pulled in that namespace. 之所以考虑使用函数int NS3::format(const NS1::Object&)是因为您拉入了该命名空间。
  • The function int NS1::format(const NS1::Object&) is considered because of ADL: The parameter is from namespace NS1 , so the matching function from NS1 will be considered as well. 由于ADL而考虑使用函数int NS1::format(const NS1::Object&) :参数来自名称空间NS1 ,因此也将考虑来自NS1的匹配函数。
  • Both functions have the exact same signature and are hence ambiguous. 这两个函数具有完全相同的签名,因此不明确。

It's worth reading What is "Argument-Dependent Lookup" (aka ADL, or "Koenig Lookup")? 值得一读什么是“依赖于参数的查询”(又名ADL或“ Koenig查找”)? as well. 也一样

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

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