【问题标题】:Functions with class arguments are leaked from a namespace?具有类参数的函数从命名空间中泄漏?
【发布时间】:2011-02-03 13:03:26
【问题描述】:

我在这里有一小段代码供您考虑,这让我很困惑。奇怪的是它可以在 Sun Studio 和 GCC 上编译,尽管我认为它不应该。

考虑一下:

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
}

来自同一命名空间的类参数导致函数f“泄漏”出命名空间,并且可以在没有name:: 的情况下访问。

有人对此有解释吗?肯定是我错了,而不是编译器错了。

【问题讨论】:

  • 有趣,BTW intel 编译器 (icpc) 也可以编译这个...
  • 编辑了我自己的问题,以删除不相关的部分,让有相同问题的其他人更容易找到。

标签: c++ namespaces argument-dependent-lookup


【解决方案1】:

它被称为argument-dependent lookup(或 Koenig 查找)。简而言之,编译器会在作为参数类型命名空间的命名空间中查找函数。

【讨论】:

  • @lytenyn:虽然它是你每天都在使用的一个 :) std::string s; s += "aa";,这里的 += 来自 std 命名空间,尽管你从未指定它,这要感谢 ADL。
  • @matthieu-m:你是完全正确的,当然,在使用 iostreams 时也是如此。但这些都是你永远不会想到的小事情,除非有人把你的鼻子推到它里面:) 另外,我不记得我读过的任何 C++ 书籍中提到过它,尽管它是如此基础。当然,这可能只是我的记忆。
【解决方案2】:

这是Argument-Dependent Name Lookup,又名 ADL,又名 Koenig 查找。这是为了使操作员按预期工作而发明的,例如:

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

如果没有 ADL,您将不得不使用丑陋的 using fu::operator&lt;&lt;; 显式地将输出运算符带入,或者使用更丑陋的显式调用:

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

【讨论】:

  • 文章很短,你的好奇心在哪里?
【解决方案3】:

这是由于“参数相关查找”。删除 const 不会改变您看到的行为。为了证明它是 ADL,请尝试将 St 结构移到命名空间之外...

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】:

    这是由参数依赖查找引起的

    【讨论】:

      猜你喜欢
      • 2011-03-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-18
      • 1970-01-01
      • 2023-03-10
      • 1970-01-01
      相关资源
      最近更新 更多