【问题标题】:C++ - Function declarations inside function scopes?C++ - 函数范围内的函数声明?
【发布时间】:2015-04-12 18:37:31
【问题描述】:

不久前我正在浏览C++11 standard draft 并遇到了这个(在第 8.3.6 节,第 204 页):

void g(int = 0, ...); // OK, ellipsis is not a parameter so it can follow

// a parameter with a default argument
void f(int, int);
void f(int, int = 7);
void h() {
    f(3); // OK, calls f(3, 7)
    void f(int = 1, int); // error: does not use default
    // from surrounding scope
}
void m() {
    void f(int, int); // has no defaults
    f(4); // error: wrong number of arguments
    void f(int, int = 5); // OK
    f(4); // OK, calls f(4, 5);
    void f(int, int = 5); // error: cannot redefine, even to
    // same value
}
void n() {
    f(6); // OK, calls f(6, 7)
}

这与函数的默认参数有关。令我印象深刻的是函数声明出现在函数范围内。这是为什么?这个功能是做什么用的?

【问题讨论】:

  • 我用它来声明一个我知道只会在作用域内调用的函数。
  • 简短的回答是它很少被使用。从理论上讲,如果(例如)你有一个同名的变量和函数,它可能会很有用。内部范围的声明将隐藏外部范围的声明。
  • stackoverflow.com/a/35007616/785194 是快速答案(对于 C)。

标签: c++ function scope declaration


【解决方案1】:

虽然我不知道你能做到这一点,但我测试了它并且它有效。我猜你可能会用它来前向声明稍后定义的函数,如下所示:

#include <iostream>

void f()
{
    void g(); // forward declaration
    g();
}

void g()
{
    std::cout << "Hurray!" << std::endl;
}

int main()
{
    f();
}

如果删除前向声明,程序将无法编译。因此,通过这种方式,您可以获得某种基于范围的前向声明可见性。

【讨论】:

  • 嗯,好的,过段时间可能会有用! :)
  • @HenriKorpela 我得说我从来不知道这一点,而且我认为我永远不会使用这样的“功能”。我非常希望能够在其他函数中 define 函数,而不需要像 staticstruct/class 中包装的常见技巧。
  • 您听说过令人烦恼的解析吗?您可能会意外地声明一个函数而不是一个实例。人们通常认为Foo f(); 声明并调用了f 的默认构造函数,但实际上它声明了一个函数。
  • 你说你不知道你可以在函数内部声明函数,但是你熟悉最令人头疼的解析,这是由于无意中在函数中声明了一个函数。
  • stackoverflow.com/questions/44943362/… 在另一个函数中声明函数的有用示例
【解决方案2】:

任何函数/变量声明都有其可见性和范围。例如,如果在课堂上,只有班级成员可以看到它。如果在函数中只有函数可以看到它,在我们声明变量或函数之后。

我们通常在函数范围内使用数据结构。但是编译器的语法规则对两者都适用,因为函数本身具有地址,因此可见性也适用于它。

【讨论】:

  • 但是你仍然可以从它下面定义的任何其他函数调用该函数,所以你只需从上面隐藏它(你不能在其他函数中定义你的函数)
  • 是的,它本质上是关于范围的。
  • 我认为这不是真的。这并不完全与范围有关,因为超出范围仍然可以使用该函数,因为您必须在全局范围内定义该函数(当然类成员除外)。只有在它上面声明的函数不能使用它。
  • 如果只有一个人可以在函数范围内实际定义/实现函数,可能会有更多好处,但遗憾的是,事实并非如此。不过,我想这是有充分理由的。
  • 声明只有在我们声明后才有作用域。即使对于变量也是如此,例如仅在循环或条件中有效的变量将仅对该块具有可见性。
猜你喜欢
  • 2011-06-12
  • 1970-01-01
  • 2016-05-05
  • 1970-01-01
  • 1970-01-01
  • 2014-12-24
  • 1970-01-01
  • 2015-06-16
相关资源
最近更新 更多