C++11 - 将非静态数据成员声明为 'auto'
C++11 - declaring non-static data members as 'auto'
如果非静态数据成员在声明中初始化,C++11 是否允许将它们声明为"auto"?例如:
struct S
{
auto x = 5; // in place of 'int x = 5;', which is definitely allowed
};
GCC 4.7 拒绝上述代码,同时接受 int x = 5;
。
假设这不是编译器错误,而是标准真的不允许它,为什么不呢?它与声明局部变量auto
一样有用。
禁止非静态成员的规则在 7.1.6.4 第 4 条中:
自动类型说明符也可用于在 中声明变量 选择语句 (6.4) 或迭代语句的条件 (6.5),在 type-specifier-seq 中的 new-type-id 或 type-id 中的 新表达式 (5.3.4)、在 for 范围声明和声明 具有大括号或等于初始值设定项的静态数据成员,该初始值设定项出现在类定义的成员规范 (9.4.2) 中。
我在这里找到了它是静态的基本原理,这反映了詹姆斯·麦克内利斯在评论中的解释。
一个国家机构不喜欢允许自动类型说明符 非静态。从给作者的电子邮件中:
template< class T > struct MyType : T { auto data = func(); static const size_t erm = sizeof(data); };
为了确定 X 的布局,我们现在有 2 阶段名称查找和 ADL。请注意,func 可以是类型或函数; 它可以在 T、MyType 的命名空间中找到,相关的 实例化时 T 的命名空间,全局命名空间,一个 匿名命名空间,或受 using 指令约束的任何命名空间。 小心的话,我们可能会concept_map寻找运气。 根据标头包含的顺序,我什至可能会得到不同的 ADL 结果,并打破一个定义规则 - 这 不需要诊断。
由于这一争议,作者不再提出汽车 允许非静态数据成员使用。
因此,基本上取决于标头包含的顺序,data
的类型可能会非常不同。当然,auto x = 5;
不需要依赖于两阶段名称查找或 ADL,但是,我假设他们将其作为"一揽子"规则,否则,他们将不得不为每个用例制定单独的规则,这将使事情变得非常复杂。
在同一篇论文中,作者建议取消此限制,但是,似乎由于上述理由,并且无论初始值设定项是什么,预期行为都可以相同,因此该提议似乎被拒绝了。
对于其他人:
使用 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>>;
我不知道怎么做,但是这个自动成员真的需要在没有他们的情况下将其变成语言,某些模式几乎是不可能的。
如果 lambda 通过引用捕获类的成员,则上述方案不起作用。对于避免使用类型擦除函数的高度可补偿类,这是一种有用的模式。我经常在嵌入式系统上做的事情。
https://godbolt.org/z/W-K9Uk
您可以将语言修改为提交,允许 lambda 使用放置新和offset_of引用不存在的类的成员,但这很荒谬,不应该是必需的。
后来的讨论在 2014 年公开总结:关键点是默认成员初始值设定项是完整的类上下文,但任何成员的类型都不是。 另一个理由是,拥有
std::vector<int> get_ints();
struct S {
auto x=get_ints();
S() : x(7,4) {}
};
使用默认成员初始值设定项的类型,否则完全忽略它。
- 将函数参数类型声明为 auto
- 如果使用返回引用的函数初始化"auto"var,为什么它不声明引用类型?
- 在 C++14 中使用 decltype(auto) 声明静态数据成员
- C++:在原型中声明"auto"函数返回类型仍然会导致在扣除错误之前使用"auto&quo
- 声明适用于 auto,但不能显式声明类型?
- auto f = bind(dist<>,gen) 在成员声明C++失败。未被识别为函数
- C++11 外部作用域变量声明为 auto
- 没有声明和初始化的类似闭包的函数(即没有'auto f = make_closure();')
- 如何处理"警告:在参数声明中使用'auto'仅适用于 -fconcepts"
- 使用新的 C++11 语法的 auto 进行函数声明,但使用 auto&并且没有 ->
- 如何使用Auto声明无效指针
- 使用 C++11 auto 关键字声明两个(或多个)变量
- 什么时候应该使用 decltype(x) 而不是 auto 来声明变量的类型
- 为什么"auto"将字符串声明为 const char* 而不是 std::string?
- 添加两个整数,但一个声明为"int",另一个声明为"auto"?
- 使用auto声明变量和使用类型名称之间的区别是什么
- 如何在C++中使用关键字"auto"声明和使用变量?
- 使用auto声明变量,并使用原始文字定义的行为进行初始化
- 无法在VS 14 CTP中使用auto声明lambda:类型为'void'的条件表达式是非法的
- 为什么基类不会在同一"auto"声明中自动推导?