初始化类成员向量的大小失败

2024-03-27

我是 C++ 新手,遇到了这个问题。这是我的代码:

class A
{
    std::vector <int> vec(10);
};

它给了我错误说expected a type specifier。我知道这种初始化向量的方式是不可接受的,应该在构造函数中完成,但我很好奇为什么会失败。我还注意到这一点:

class A
{
    std::vector <int> vec = std::vector<int>(10);
};

工作得很好。

所以我的问题是为什么第二种情况有效,即使我们仍在创建具有“预定义大小”的向量(std::vector<int>(10)),为什么第一个案例失败了?谢谢。

P.S我正在尝试创建大小为 10 个整数的向量,而不是使用 with 创建向量10已经插入其中了。


What?

从 C++11 开始,我们有非静态数据成员初始化器 https://en.cppreference.com/w/cpp/language/data_members,使得这种初始化成员的方法完全有效。然而,你must使用任一= or {}.

Formally, if an initializer is present here, it must be http://eel.is/c++draft/class.mem with a brace-or-equal-initializer http://eel.is/c++draft/dcl.init#nt:brace-or-equal-initializer grammatical production.

由于您在此处使用了不计为初始化的语法,因此编译器会尝试使用以下形式进行函数声明:vec,这会破坏,因为20不是一个类型。


Why?

原始特征提案中名为“问题1”的章节(N2756 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2756.htm)解释说()此处不允许使用,以避免与成员函数声明有关的一些混淆。

作者在其中确实指出,委员会could顺其自然,让它像其他声明一样工作——也就是说,如果可以的话,它就是一个函数,否则就是一个对象*。但作者决定采取不同的方向,只是禁止语法以避免这种特殊情况下的问题。

不幸的是,这使得“(表达式列表)” 在解析声明时形式不明确 [..]

一种可能的解决方案是依赖现有规则,即如果声明可以是对象或函数,那么它就是函数 [..]

类似的解决方案是应用另一个现有规则,当前仅在模板中使用,如果T可能是一种类型或其他东西,那么它就是其他东西;我们可以使用“typename“如果我们真的指的是一种类型[..]

这两种解决方案都引入了可能被许多用户误解的微妙之处(正如 comp.lang.c++ 上关于为什么“的许多问题所证明的那样”int i();” 在块范围内不声明默认初始化int).

本文提出的解决方案是仅允许“=”的初始化器初始化子句“ 和 ”{初始化列表}“ 形式。这解决了大多数情况下的歧义问题。

这就是人生。


So?

我正在尝试创建大小为 10 个整数的向量,而不是创建已插入 10 个整数的向量。

这是很重要的一点。小心,因为初始化一个向量{} 不会那样做 https://medium.com/@barryrevzin/uniform-initialization-isnt-82533d3b9c11。不幸的是“统一”初始化只是增加了更多的含义 https://xkcd.com/927/。解决歧义问题就这么多了……

因此,您应该使用=语法,或者只是在构造函数中执行此操作(我最喜欢的)。


* This is where the most vexing parse https://en.wikipedia.org/wiki/Most_vexing_parse can sometimes bite you, though not every occurrence of unintended function declarations is an example of the most vexing parse.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

初始化类成员向量的大小失败 的相关文章

随机推荐