我是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)
)的向量,为什么第二种情况仍然有效,为什么第一种情况会失败?谢谢。
PS
我正在尝试创建大小为10个整数的矢量,而不是创建带有10
的矢量。
答案 0 :(得分:7)
自C ++ 11起,我们有了non-static data member initialisers,使初始化成员的方法完全有效。 但是,您必须使用=
或{}
。
形式上,如果此处存在初始化程序,则it must be的语法形式为brace-or-equal-initializer。
由于您在这里使用了不算作初始化的语法,因此编译器会尝试从vec
进行函数声明,因为20
不是类型,所以这会中断。 / p>
原始功能建议(N2756)中名为“问题1”的章节解释说,此处()
被禁止,以避免对成员函数声明造成混淆。
作者确实在其中指出,委员会可以允许,并且可以像其他声明一样工作—即,如果可以的话,它是一个函数,否则为对象*。但是作者决定朝另一个方向发展,只是禁止使用语法以避免在这种特殊情况下出现问题。
不幸的是,这使得在解析声明时“( expression-list )”形式的初始值设定项不明确 [..] < / em>
一种可能的解决方案是依靠现有规则,即如果声明可以是对象或函数,那么它就是函数 [..] >
一种类似的解决方案是应用另一条仅在模板中使用的现有规则,即如果
,则可以使用“T
可以是类型或其他类型,则为其他类型;如果确实是类型 [..]typename
”这两种解决方案都引入了许多用户可能会误解的细微之处(如comp.lang.c ++上有关“为什么
int i();
”在块范围内出现的许多问题所证明的那样没有声明默认初始化的int
)。本文提出的解决方案是仅允许使用“ = initializer-clause ”和“ { initializer-list }”形式的初始化器。 / strong>在大多数情况下都可以解决歧义性问题。
生活就是这样。
我正在尝试创建大小为10个整数的矢量,而不是创建已经插入10个矢量的矢量。
这是重要的一点。小心,因为用{}
won't do that初始化向量。不幸的是,“统一”初始化merely added more meanings。解决歧义问题的事就这么多了……
因此,您应该使用=
语法,或者只在构造函数中使用(我最喜欢)。
*这是most vexing parse有时会咬你的地方,尽管并非每次意外的函数声明都是最令人头疼的解析例子。
答案 1 :(得分:1)
它写得不好。您也可以使用以下示例。在这里,我将向量保留为空,但是console.log (res)
空间可容纳20个指针,因此您可以插入而不必重新分配。 (使用构造函数)更简单,更好的解决方案是:
A.cpp
reserve()
A.hpp
#include "A.hpp"
A::A()
{
this->vec.reserve(20);
std::cout << "Setting size" << std::endl;
}
A::~A()
{
}
main.cpp
#ifndef A_HPP
#define A_HPP_
#include <iostream>
#include <vector>
class A {
public:
A();
~A();
std::vector<int> vec;
};
#endif /* !A_HPP_ */
输出:
#include "A.hpp"
int main()
{
A a;
}
向量大小完成了。
答案 2 :(得分:0)
不允许使用语法type name(value);
声明和初始化成员变量,但可以使用type name{value};
或type name = value;
。
这是标准中的语法:
[class.mem]/1
member-declaration: attribute-specifier-seq(opt) decl-specifier-seq(opt) member-declarator-list(opt); [...] member-declarator-list: member-declarator member-declarator-list , member-declarator member-declarator: [...] declarator brace-or-equal-initializer(opt) [...]
和
[dcl.init]/1
brace-or-equal-initializer: = initializer-clause braced-init-list braced-init-list: { initializer-list , (opt) } { designated-initializer-list , (opt) } { }
以下内容:
class C
{
int a = 0;
int b{0};
}
有效。
C::a
的定义是一个成员声明,其中的 member-declarator-list 由单个成员组成,并以括号初始化。形式为= initializer-clause
的等号初始化器。
类似地,C::b
使用 braced-init-list 形式。
另一方面,您找不到int c(0);
的语法。