哪个查找规则阻止编译器找到该函数?

lar*_*ars 18 c++

void Foo(int i)
{
}
struct Bar
{
    static void Foo() { Foo(1); }
};
Run Code Online (Sandbox Code Playgroud)

上面的代码没有编译.它找不到Foo(int).为什么?我知道它与具有相同的功能名称有关,但没有进一步了解问题.

为什么我需要合格的查找?

Arm*_*yan 25

从3.4.1开始(强调我的)

在3.4.1中列出的所有情况下,在每个相应类别中列出的顺序中搜索范围; 一旦找到名称的声明,名称查找就会结束.如果没有找到声明,该程序就是格式错误.

在这种特殊情况下,要搜索的第一个范围是函数局部范围.在那里找不到Foo.然后是类范围.由于在其中找到了名称Foo,因此名称查找在那里停止,而另一个Foo根本不参与重载决策.


Bat*_*eba 18

如果特定命名空间中的函数与全局命名空间中的函数名称相同,则找不到全局命名空间中的函数.

遗憾的是,C++标准不允许您使用适当的using语句将全局命名空间引入当前命名空间,尽管您可以使用它using ::Foo;来引入该特定函数:

void Foo(char)
{
}

struct Bar
{
    static void Foo(double) { }
    static void Foo() {
        using ::Foo;
        Foo('c'); // correct overload is found since ::Foo is pulled into scope
        Foo(3.0);
    }
};
Run Code Online (Sandbox Code Playgroud)

否则,您需要使用范围解析运算符来查找全局函数:

struct Bar
{
    static void Foo() { ::Foo(1); }
};
Run Code Online (Sandbox Code Playgroud)

  • @skm - 它被称为[使用声明](http://en.cppreference.com/w/cpp/language/using_declaration).旧的C++本身,但许多教程由于某种原因略过它......想想看,一般的命名空间在大多数教程中都没有得到应有的尊重,而且这些都很有用. (3认同)
  • 好吧,[可以拉出那个特定的名字](http://coliru.stacked-crooked.com/a/710ef3787ff67c7e),并从那一点开始使用不合格的查找 (2认同)