【问题标题】:Why doesn't the C++11 'auto' keyword work for static members?为什么 C++11 'auto' 关键字对静态成员不起作用?
【发布时间】:2013-01-11 19:22:53
【问题描述】:
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+ 中的错误

【问题讨论】:

  • "foo" 并不是真正的const char*,而是const char[4]
  • 不确定你想在这里用 auto 实现什么。 constant_string 已经被声明,静态初始化应该没有 auto 就可以了。

标签: c++ c++11 auto


【解决方案1】:

语言不允许:

[C++11: 7.1.6.4]:

1auto type-specifier 表示被声明的变量的类型应该从它的初始化器中推导出来,或者函数声明符应该包含一个 尾随返回类型

2auto type-specifier 可能与带有 trailing-return-type 的函数声明符一起出现 (8.3.5)在此类声明符有效的任何上下文中。

3 否则,变量的类型是从它的初始化器推导出来的。被声明的变量的名称不应出现在初始化表达式中。在块 (6.3)、命名空间范围 (3.3.6) 和 for-init-statement (6.5.3) 中声明变量时,允许使用 autoauto 应作为 decl-specifier-seq 中的 decl-specifiers 之一出现,并且应遵循 decl-specifier-seq由一个或多个init-declarators,每个都应有一个非空的initializer

4auto 类型说明符也可用于条件中声明变量new-type-idtype-id 中的 type-specifier-seq 中的选择语句 (6.4) 或迭代语句 (6.5) new-expression (5.3.4) 中的 ,在 for-range-declaration 中,以及在声明带有 brace-or-equal 的静态数据成员中-initializer 出现在类定义的成员规范中 (9.4.2)。

5在本节未明确允许的上下文中使用 auto 的程序是格式错误的。

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

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

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

int main() {}

(注意Foo::constant_string 的类型是char const* const 而不是char const[3]this is an effect of using auto。)

【讨论】:

  • +1 原因是这种情况会很尴尬:struct foo { static long x; }; auto foo::x = 0; 初始化器说类型应该是int,但声明说它应该是longauto 是否应该强制转换初始化程序(它在没有其他上下文的情况下执行此操作),它是否应该无法编译,或者 auto 是否应该重用现有类型(因此除了减轻程序员打字之外没有什么作用),需要更多的措辞在标准中?我敢肯定这件事出现了,并且决定做最简单的事情:完全禁止它。
  • @GManNickG:同意。鉴于此,我很惊讶没有明确提及,即使只是在 Note 中。
  • -1,每个定义都是一个声明(在这种情况下,定义也是一个重新声明,因为它第二次声明了变量)。第 1 段允许他给出的例子(第 4 段中出现的一些内容似乎是多余的,因为第 1 段已经允许了)。
  • @gman 我们现有的规则规定每次重新声明都应指定相同的类型。当您将 auto 替换为 int 时,同样的情况也适用。链接规则使这种情况不正确,不需要诊断。
  • 除了那句话是C++对“定义”这个词的定义。你可以看出来,因为这个词是斜体的。
【解决方案2】:

Visual C++ 接受

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

【讨论】:

    猜你喜欢
    • 2020-11-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多