c – 在没有限定条件的名称空间中调用函数

前端之家收集整理的这篇文章主要介绍了c – 在没有限定条件的名称空间中调用函数前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
看一下boost :: polygon的源代码,我看到了以下主题的许多应用:
#include <iostream>

namespace B {

struct A {
  void foo() const { std::cout << "foo" << std::endl; }
};

void bar(const A &a) { a.foo(); }
void baz() { std::cout << "baz" << std::endl; }

}

int main(int argc,char **argv) {
  B::A a;
  bar(a);
  B::baz(); // simply calling baz() does not work

  return 0;
}

如果没有额外的资格,可以如何调用bar(a)?我原以为只有B :: bar(a)会编译.

函数在命名空间内没有参数时,不会发生这种情况.

解决方法

根据ISO C 14标准,§3.4.2:

When the postfix-expression in a function call is an unqualified-id,other namespaces not considered during the usual unqualified lookup may be searched,and in those namespaces,namespace-scope friend function or function template declarations not otherwise visible may be found. 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. The sets of namespaces and classes is determined entirely by the types of the function arguments..

If T is a class type (including unions),its associated classes are: the class itself; the class of which it is a member,if any; and its direct and indirect base classes. Its associated namespaces are the innermost enclosing namespaces of its associated classes.

实际上你甚至可以通过附上函数名来防止这种情况发生:

(bar)(a); // doens't compile

(B::bar)(a); // does compile

还要注意,这仅适用于最里面的命名空间,这意味着在以下情况下,您需要限定命名空间:

namespace B {
   namespace C {
     struct A {};
   }

   void bar(const C::A& a) { ... }
}

猜你在找的C&C++相关文章