为什么静态成员函数只有在具有 return 值的情况下才能在全局范围内调用?

Why can static member functions only be called at global scope if they have a return value?

我发现了一件奇怪的事情:class/struct 的静态成员函数不能称为全局范围,除非它们具有 return 值。

此程序无法编译:

struct test
{
  static void dostuff()
  {
      std::cout << "dostuff was called." << std::endl;
  }
};

test::dostuff();

int main()
{  
   return 0;
}

在 GCC v4.8.3 下为我们提供以下内容:

main.cpp:12:16: error: expected constructor, destructor, or type conversion before ';' token
test::dostuff();
               ^

但是,通过将 return 值添加到 dostuff() 并将其分配给全局变量,程序将按预期编译和运行:

struct test
{
  static int dostuff()
  {
      std::cout << "dostuff was called." << std::endl;
      return 0;
  }
};

int i = test::dostuff();

int main()
{
   return 0;
}

这会产生预期的输出:

dostuff was called.

谁能向我解释为什么会这样,是否有不涉及创建全局变量的解决方法?

您不能在全局范围内调用函数,因为从 [basic.link]

A program consists of one or more translation units (Clause 2) linked together. A translation unit consists of a sequence of declarations.

test::dostuff(); 不是声明 - 所以你不能将它作为一个独立的函数调用(它是一个静态成员函数的事实是无关紧要的 - 可以是一个自由函数,一个非静态成员函数调用在全局对象上,等等)。另一方面,int i = test::dostuff(); 声明:在全局范围内属于 int 类型的变量 i。这就是它被允许的原因。请注意,dostuff() 具有相关的 return 值并不是事实 - 这是您声明具有该 return 值的变量的事实。

这就是 C++ 的工作方式——通常,代码属于函数。 "Global" 代码属于主函数,main,它在程序启动时开始执行。

main 开始之前可能执行的唯一代码是全局(静态和命名空间范围)变量的初始化程序,例如示例中的 i。但是您不应该将其用作 "this is how to execute code at global scope." 应按其预期用途使用:"this is how to initialise a global variable."

如果在程序开始时需要 运行 的代码,请将其放在 main 的开头。很少需要代码 运行 before 它自己,而不关心它的 return 值。如果您确实发现自己处于这种情况,伪造初始化是一种可能的解决方法。但请记住注意事项,例如此类 before-main 代码执行的顺序通常未指定。