Functions with class arguments are leaked from a namespace?

跟風遠走 提交于 2019-12-03 07:43:46

问题


I have a small piece of code here for your consideration which puzzles me quite a lot. The strange thing is that it compiles on both Sun Studio and GCC even though I think it should not.

Consider this:

namespace name
{
  class C
    {
      int a;
    };

  void f(C c);
  void g(int a);
}

int main(int argc, char** argv)
{
  name::C c;

  name::f(c); 
  f(c);  // <--- this compiles, strangely enough

  name::g(42);
  // g(42);  <--- this does not, as I expected
}

The class argument from the same namespace causes the function f to 'leak' out of the namespace and be accessible without name::.

Does anybody have an explanation for this? It is certainly me and not the compiler being wrong here.


回答1:


It's called argument-dependent lookup (or Koenig lookup). In short, the compiler will look for the function in namespaces that are the namespaces of argument types.




回答2:


This is Argument-Dependent Name Lookup, a.k.a. ADL, a.k.a. Koenig lookup. This was invented to make operators work as expected, e.g.:

namespace fu {
    struct bar { int i; };
    inline std::ostream& operator<<( std::ostream& o, const bar& b ) {
        return o << "fu::bar " << b.i;
    }
}

fu::bar b;
b.i = 42;
std::cout << b << std::endl; // works via ADL magic

Without ADL you'd have to either explicitly bring the output operator with ugly using fu::operator<<;, or use even uglier explicit call:

fu::operator<<( std::cout, b ) << std::endl;



回答3:


It's due to "argument dependent lookup". Removing the const will not change the behavior you're seeing. To demonstrate that it's ADL, try moving the St struct outside of the namespace...

struct St
{
   int a;
};

namespace name
{
  void f(const St& st);
  void g(int a);
}

int main(int argc, char** argv)
{
  St st;

  name::f(st); 
  f(st);  // <--- now you will get the expected compile error

  name::g(42);
  // g(42);  <--- this does not, as I expected
}



回答4:


That is caused by argument dependent lookup.



来源:https://stackoverflow.com/questions/4886478/functions-with-class-arguments-are-leaked-from-a-namespace

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!