C++ 11 - 将非静态数据成员声明为"auto"

HC4*_*ica 46 c++ variable-declaration auto c++11

如果在声明中初始化了非静态数据成员,它们是否允许将非静态数据成员声明为"auto"?例如:

struct S
{
    auto x = 5;  // in place of 'int x = 5;', which is definitely allowed
};
Run Code Online (Sandbox Code Playgroud)

GCC 4.7拒绝上述代码,但它接受了int x = 5;.

假设这不是编译器错误,而是标准真的不允许它,为什么不呢?它与声明局部变量一样有用auto.

Jes*_*ood 63

禁止非静态成员的规则见7.1.6.4第4条:

auto-type-specifier也可用于在选择语句(6.4)或迭代语句(6.5)的条件中声明变量,在new-type-id或type-id中的type-specifier-seq中new-expression(5.3.4),在for-range-declaration中,并声明一个 静态数据成员,其具有在类定义的成员规范中出现的大括号或等于初始值(9.4.2) .

我发现它在这里是静态的理由反映了James McNellis在评论中如何解释它.

一个国家机构不喜欢允许自动类型指定器用于非静力学.从电子邮件到作者:

    template< class T >
    struct MyType : T {
      auto data = func();
      static const size_t erm = sizeof(data);
    };
Run Code Online (Sandbox Code Playgroud)

为了确定X的布局,我们现在有两阶段名称查找和ADL.请注意,func可以是类型或函数; 它可以在T中找到,MyType的命名空间,实例化时T的关联命名空间,全局命名空间,匿名命名空间或任何使用using指令的命名空间.小心翼翼,我们可能会为了运气而抛出一些concept_map查找.根据标题包含的顺序,我甚至可能得到不同的ADL结果,并打破一个定义规则 - 不需要诊断.

由于这种争议,作者不再建议允许自动允许非静态数据成员.

因此,基本上取决于包含头的顺序,类型data可能会有很大不同.当然,auto x = 5;不需要依赖于两阶段名称查找或ADL,但是,我假设他们将其作为"一揽子"规则,否则,他们必须为每个用例制定单独的规则事情很复杂.

在同一篇论文中,作者建议消除这一限制,但是,似乎这个提议可能由于上述原理而被拒绝,并且无论初始化程序是什么,预期行为都可以是相同的.

  • 感谢您深入研究,这是一个有趣的理由! (8认同)
  • 这个理由也不适用于`decltype(func())data = func()`,这现在合法吗? (4认同)
  • NB允许它的原始提案是[N2426](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2426.htm) (2认同)
  • 我不明白为什么“static”会产生影响。我缺少什么? (2认同)

Dav*_*ger 6

为他人:

使用 C++17,这是可以间接实现的(自动推导非静态成员类型)。你需要使用模板和推导指南来实现它:

template< class data_t>
struct MyType 
{
    data_t data;
    static constexpr auto data_size = sizeof(data_t);

    MyType( data_t && p_data ) : data(p_data) {}
};

template< class data_t>
MyType(data_t &&) -> MyType<std::remove_reference_t<data_t>>;
Run Code Online (Sandbox Code Playgroud)

我不知道怎么做,但这个汽车成员确实需要将其融入到语言中,如果没有他们,某些模式几乎是不可能的。

如果 lambda 通过引用捕获类的成员,则上述场景不起作用对于避免使用类型擦除函数的高度可补偿类来说,这是一种有用的模式。我经常在嵌入式系统上做的事情。

https://godbolt.org/z/W-K9Uk

您可以将语言修改为提交,允许 lambda 使用placement-new 和 offset_of 引用不存在的类的成员,但这是可笑的,不应该是必需的。

  • 我不明白这是怎么一个答案。该类没有声明为“auto”的数据成员。 (6认同)