为什么静态成员函数只有在具有 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
代码执行的顺序通常未指定。
我发现了一件奇怪的事情: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
代码执行的顺序通常未指定。