C+ 11-声明非静态数据成员为' auto'
C ++ 11是否在声明中初始化了非静态数据成员为“自动”?例如:
struct S
{
auto x = 5; // in place of 'int x = 5;', which is definitely allowed
};
GCC 4.7拒绝上述代码,而它接受 int x = 5;
。
假设这不是编译器错误,而是标准确实不允许,为什么不呢?它与声明本地变量 auto
一样有用。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
禁止非静态成员的规则在7.1.6.4第4条中:
我发现它的理由是静态的在这里在评论中解释。
因此,基本上,根据标头包含的顺序,
数据的类型
可能会大不相同。当然,auto x = 5;
不需要依赖2相名称查找或ADL,但是,我假设他们将其制定为“毯子”规则,因为否则,他们将必须为每种用例制定个人规则,这将使事情变得非常复杂。在同一篇论文中,作者提出消除这种限制,但是,似乎由于上述理由而被拒绝了,因此无论初始化器是什么,预期行为都可以相同。
The rule for prohibiting non-static members is in 7.1.6.4 clause 4:
I found the rationale for it being static here which reflects how James McNellis explains it in the comment.
So, basically depending on the order of header inclusion, the type of
data
could be very different. Of course,auto x = 5;
would not need to depend on 2-phase name lookup or ADL, however, I'm a assuming that they made it a "blanket" rule because otherwise, they would have to make individual rules for every use case which would make things very complicated.In the same paper, the author proposes eliminating this restriction, however, it seems this proposal has been rejected probably due to the above rationale and also so that expected behavior can be the same no matter what the initializer is.
对于其他人:
使用C ++ 17这是间接的(非静态成员类型的自动扣除)。您需要使用模板和扣除指南来实现它:
我不知道该怎么做,但是这款汽车成员确实需要将其纳入语言,而没有某些模式几乎是不可能的。
如果Lambda通过参考捕获了班级成员,则以上方案 工作。对于避免使用类型擦除功能的高度补偿类来说,这是一个有用的模式。我经常在嵌入式系统上做的事情。
https://godbolt.org/z/w-k9uk
您可以将语言误用在提交中使用位置new和offset_of引用不存在类的lambda,但这是可笑的,不需要。
For others:
Using C++17 this is indirectly (automatic deduction of non-static member type) possible. You need to use templates and deduction guides to make it happen:
I don't know how but this auto members really need to make it into the language without them certain patterns are next to impossible.
The scenario above does not work if the lambda captures a member of class by reference. This is a useful pattern for, highly compensable classes that avoid the use of type erased functions. Something I regularly do on embedded systems.
https://godbolt.org/z/W-K9Uk
You can mangle the language into submission allowing a lambda to reference a member of a non-existent class using placement-new and offset_of but that is ludicrous and shouldn't be required.
后来的讨论是完整级上下文任何成员的类型都不是。另一个理由是,
尽管完全忽略了默认会员初始化器的 type ,否则将是奇怪的。
Later discussion was publicly summarized in 2014: the critical point was that a default member initializer is a complete-class context but the type of any member is not. One further bit of rationale is that it would be odd to have
use the type of the default member initializer despite completely ignoring it otherwise.