【问题标题】:Declaring a Static Data Member with decltype(auto) in C++14在 C++14 中使用 decltype(auto) 声明静态数据成员
【发布时间】:2017-03-24 13:58:50
【问题描述】:

此代码是否符合标准?

class Example {
    public:
        static int x;
};

decltype(auto) Example::x = 1;

int main(){ return 0; }

Clang 3.9.1 编译成功,但 gcc 6.3.0 失败:error: conflicting declaration 'decltype(auto) Example::x'

C++14 标准 (ISO/IEC 14882:2014),第 7.1.6.4 节,第 5 段(强调我的):

占位符类型也可用于在 type-specifier-seq 在 new-expression (5.3.4) 的 new-type-idtype-id 中,在 for-range-declaration,以及在声明一个带有 brace-or-equal-initializer 的静态数据成员时出现在 member-specification 类定义 (9.4.2)

(重新)声明并不严格在类定义的成员规范中,但我看不出有什么好的理由禁止它。此外,它也可以看作是对命名空间范围内的变量(静态数据成员变量)的(重新)声明,这在第 4 段中是允许的:

使用 auto 或 decltype(auto) 声明的变量的类型是从其初始化程序推导出来的。在块 (6.3)、命名空间范围 (3.3.6) 和 for-init-statement (6.5.3) 中声明变量时,允许使用这种用法。

有一个类似的 C++11 帖子:Why doesn't the C++11 'auto' keyword work for static members? 然而,只有一个答案,然后在 cmets 中开始了一场辩论。此外,在这种情况下,clang 通常更可靠,根据这个答案,clang 是错误的,而 gcc 是正确的。

【问题讨论】:

  • 我认为标准的意图(我认为它打算禁止这样做)以及它实际需要什么(我认为它实际上允许这样做)并不是很清楚。另见stackoverflow.com/questions/26386010
  • @Darklighter 在您提供的链接中进行了有趣的讨论,顺便说一句,我同意您的观点,所以我假设我不能依赖此功能的行为。感谢您的评论。

标签: c++ c++14 static-members auto decltype


【解决方案1】:

gcc 似乎变得很困惑,因为它试图从其初始化中的右值推断x 的类型,而 NOT 它在Example 类中的声明。这可能会导致两种类型之间的不一致,从而看起来您正在定义一个具有相同名称的新变量。

如果我理解正确,您正在寻找的行为可以使用符合标准的代码来实现,方法是使用从变量声明中显式推断类型的宏:

#define auto_typed_init(a) decltype(a) a

(...)

auto_typed_init(Example::x) = 2;

但是,我不明白为什么标准在这种情况下偏爱初始化程序,正如这个答案中所解释的那样:Why doesn't the C++11 'auto' keyword work for static members?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-09
    • 2012-07-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多