void foo (int x)
{
struct A { static const int d = 0; }; // error
}
除了标准的引用之外,是否有任何动机可以禁止内部类中的static
字段?
error: field `foo(int)::A::d' in local class cannot be static
修改:但是,允许使用static
个成员函数。对于这种情况,我有一个用例。假设我只想为POD调用foo()
,那么我可以像
template<typename T>
void foo (T x)
{
struct A { static const T d = 0; }; // many compilers allow double, float etc.
}
foo()
应该只传递POD(如果允许static
)而不传递给其他数据类型。这只是我脑海中的一个用例。
答案 0 :(得分:5)
Magnus Skog给出了真正的答案:静态数据成员只是一个声明;该对象必须在其他地方定义,在命名空间范围内,并且类定义在命名空间范围内不可见。
请注意,此限制仅适用于静态数据成员。这意味着有一个简单的解决方法:
class Local
{
static int& static_i()
{
static int value;
return value;
}
};
这为您提供了完全相同的功能,但代价是 使用函数语法来访问它。
答案 1 :(得分:4)
我想这是因为必须在全局范围内定义静态类成员。
编辑:
对不起是一个懒鬼,只是丢掉东西:)更准确一点。需要在全局范围内定义类的静态成员,例如
foo.h中
class A {
static int dude;
};
Foo.cpp中
int A::dude = 314;
现在,由于void foo(int x)中的作用域不是全局的,因此没有用于定义静态成员的作用域。希望这更清楚一点。
答案 2 :(得分:4)
因为没有人认为有任何需要吗?
[edit] :静态变量只需要定义一次,通常在类之外(内置函数除外)。在本地类中允许它们也需要设计一种定义它们的方法。的 [/编辑] 强>
添加到某种语言的任何功能都有费用:
有时,未实施功能是正确的决定。
本地函数和类会给语言增加难度,但收效甚微:使用static
函数和未命名的命名空间可以避免使用它们。
一个例子:The Most Vexing Parse。
答案 3 :(得分:0)
我认为这是同样的命名问题阻止我们在模板实例化中使用本地类型。
名称foo()::A::d
不是链接器要解析的好名称,那么它应该如何找到静态成员的定义?如果函数baz()中有另一个结构A怎么办?
答案 4 :(得分:0)
有趣的问题,但我很难理解你为什么想要本地班级的静态成员。静态通常用于维护程序流的状态,但在这种情况下使用范围为foo()
的静态变量不是更好吗?
如果我不得不猜测为什么存在限制,我会说这与编译器知道何时执行静态初始化的难度有关。 C ++标准文档可能提供更正式的理由。
答案 5 :(得分:0)
只是因为。
关于C ++的一件令人讨厌的事情是,它对“全局上下文”概念有很强的依赖性,在此概念中,所有事物都必须唯一地命名。甚至嵌套的名称空间机制也只是字符串欺骗。
我想(只是一个疯狂的猜测)一个严重的技术问题正在与为C设计的链接器一起使用,并且进行了一些调整才能使其与C ++一起使用(并且C ++代码需要C互操作性)。
能够获得任何C ++代码并“包装”它以便能够在一个较大的项目中使用而不会发生冲突是很好的,但是由于链接问题,情况并非如此。我认为在功能级别上禁止使用静态方法或非内联方法(甚至是嵌套函数)没有任何合理的哲学理由,但这是我们目前所得到的。
即使声明/定义对偶及其所有烦人的冗长性和含义也与实现问题有关(并且可以在不提供源代码的情况下提供出售可用的目标代码的能力,但由于良好的原因,这种情况现在不那么受欢迎了)。