5

为什么会这样编译?

int main() {
    void f();
}

是什么f?它是函数还是变量,我该如何使用它?

4

6 回答 6

6

你有一个函数声明。在块作用域内声明函数是可以的。在块中定义函数是不可能的。仅在本地声明一个函数是非常好的,例如,当您想引用其他一些现有函数时:

int main()
{
    int foo();
    return foo();
}

您只需将其与一些定义int foo();.

(这样做可能不是很好的做法,因为它隐藏了您的代码对另一个函数的依赖关系,如果不仔细阅读代码,几乎不可能看到。)

请注意,本地声明隐藏了函数的其他重载,因此参数查找可能与您在全局范围内声明函数时不同。请参阅@David Rodríguez 的更详细的答案。

于 2013-09-27T18:42:54.127 回答
5

这是与 C 的一个旧的向后兼容功能,它允许在范围内(函数级别或函数内的范围)声明函数。C 中的效果很简单,它提供了与常规函数声明等价的功能,但名称仅在此范围内可见,因此编译器在当前范围之外无需关心它。

在 C++ 中,事情要复杂一些。拥有命名空间需要更复杂的查找规则,拥有重载需要重载解析。在一些早期版本的标准中,本地函数声明应该隐藏任何其他同名的函数声明(这通常与查找一致)并禁用参数相关查找是被接受的。毕竟,如果用户声明它如此接近使用,她一定希望这个函数被调用。一段时间后,有人推动从语言中完全删除该功能,但供应商遇到了希望为现有客户端代码库支持它的供应商。

这会直接影响可见的函数重载,进而影响调用的内容。这是危险的,因为大多数人不知道查找差异,应该避免。这意味着什么的一些例子:

namespace A {
   struct B {
      operator int();
   };
   void g(B const&);
}
void f(int);
void f(double);
void g(int) {
   void f(double);
   f(1);               // calls f(double)
}
int main() {
   void g(int);
   A::B x;
   g(x);               // calls g(static_cast<int>(x))
}

在内部g(int),调用f(1)似乎是 match ::f(int),但本地声明隐藏了重载并::f(double)作为唯一的解决方案留下,并且在将值转换为 a 后使用重载double。在 内部main,局部声明禁用了参数依赖查找,并强制使用::g(int),为此对象x转换为int.

如果没有本地函数声明,代码将分别调用f(int)::A::g(::A::B const&),这是大多数开发人员所期望的。

于 2013-09-27T18:59:41.863 回答
2

在功能块中声明一个功能是完全可以的。但是在功能块中定义它时会出错。

int main()
{
    void func();      //fine
    void func() { }   //error
}
于 2013-09-27T18:44:01.880 回答
2

不能在另一个函数内 定义/创建一个函数,但您可以在另一个函数内声明一个函数。

int main()
{
    void foo();  //ok

    void foo() {
    }   //error
}
于 2013-09-27T18:45:36.340 回答
1

允许函数声明,不允许函数定义。

但是,以下是定义明确的代码:

#include <iostream>

int main()
{
    // void function() {}; //  a function-definition is not allowed
    struct Function {
        static void apply() {
            std::cout << "Hello World" << std::endl;
        }
    };

    Function::apply();
} 
于 2013-09-27T18:55:56.863 回答
0

f 是返回类型为 void 的函数的标识符(名称),这里的函数只是在 main 函数中调用才能使用它,你必须声明和定义它这里是语法

void f();       //before main function declaration 
int main()      //main 
{}
void f();       //define here the function f.

最后但并非最不重要的一点是,当且仅当您首先声明和定义它时,您才能使用(调用函数来做一些有用的工作)这个函数。

于 2013-09-27T18:53:21.140 回答