问题 为什么C ++ 11'auto'关键字不能用于静态成员?


class Foo {
 public:
  static const char *constant_string;
};

auto Foo::constant_string = "foo";

int main(void) {
};

编译:gcc(Ubuntu / Linaro 4.6.3-1ubuntu5)4.6.3像这样:

gcc -std=c++0x ./foo.cc 
./foo.cc:6:11: error: conflicting declaration ‘auto Foo::constant_string’
./foo.cc:3:22: error: ‘Foo::constant_string’ has a previous declaration as ‘const char* Foo::constant_string’
./foo.cc:6:11: error: declaration of ‘const char* Foo::constant_string’ outside of class is not definition [-fpermissive]

这是预期的行为吗? auto 关键字,或gcc +中的错误


10282
2018-01-11 19:22


起源

"foo" 不是真的 const char* 但 const char[4]。 - Bo Persson
不知道你想用auto做什么。 constant_string已经声明,静态初始化应该没有auto。 - kchoi


答案:


它被语言所禁止:

[C++11: 7.1.6.4]:

1 该 auto  类型说明符 表示声明的变量的类型应从其初始化程序推断出,或者函数声明符应包括a 尾随收益型

2 该 auto  类型说明符 可能会出现带有函数声明符的 尾随收益型 (8.3.5)在此类声明者有效的任何情况下。

3 否则,从其初始化程序推导出变量的类型。声明的变量的名称不应出现在初始化表达式中。这个用法 auto 在块(6.3),命名空间范围(3.3.6)和a中声明变量时允许使用 换初始化语句 (6.5.3)。 auto 应作为其中之一出现 DECL,符 在里面 DECL说明符-SEQ 和 DECL说明符-SEQ 之后应有一个或多个 初始化声明符,每个都应该是非空的 初始化

4  auto  类型说明符 也可以使用 在声明中的变量 条件 选择语句(6.4)或迭代语句(6.5),在 类型说明符-SEQ 在里面 新型-ID 要么 类型ID 一个 新的表达 (5.3.4),在范围声明中,和 用a声明一个静态数据成员 大括号或相等的初始值设定 出现在 构件规格 类定义 (9.4.2)。

  一个使用的程序 auto 在本节未明确允许的上下文中,格式不正确。

很难证明是消极的,但标准中根本没有明确的规则允许 auto 在你的情况下。

但是,相同的规则意味着以下内容  有效:

struct Foo {
   static constexpr auto constant_string = "foo";
};

int main() {}

(注意类型 Foo::constant_string 是 char const* const 而不是说, char const[3]; 这是使用的效果 auto。)


10
2018-01-11 19:28



+1原因是这种情况会很尴尬: struct foo { static long x; }; auto foo::x = 0; 初始化程序说类型应该是 int,但声明说它应该是 long。应该 auto 如果编译失败,或者应该编译初始化器(它在其他任何上下文中都没有) auto 重用现有的类型(因此没有什么用处,只是为了减轻程序员的打字),需要在标准中加入更多的措辞?我确信这就出现了,决定做最简单的事情:完全禁止它。 - GManNickG
@GManNickG:同意。鉴于此,我很惊讶没有明确提及,即使只是在一个 注意。 - Lightness Races in Orbit
-1,每个定义都是一个声明(在这种情况下,定义也是重新声明,因为它第二次声明变量)。第1段允许他给出的例子(第4段中出现的一些内容似乎是多余的,因为第1段已经允许这样做)。 - Johannes Schaub - litb
@gman我们有现有的规则,即每次重新声明都应指定相同的类型。当你用int替换auto时,同样的场景也适用。连锁规则使得这个案例不合格,不需要诊断。 - Johannes Schaub - litb
除了句子是C ++对“定义”这个词的定义。你可以说,因为这个词是斜体的。 - aschepler


Visual C ++接受

decltype(Foo::constant_string) Foo::constant_string = "foo";

2
2017-07-31 14:52