接下来的几行我将来自“The C ++ Standard Library - A tutorial and reference”一书。
使用标准输入进行初始化:
//read all integer elements of the deque from standard input
std::deque<int> c((std::istream_iterator<int>(std::cin)),
(std::istream_iterator<int>()));
不要忘记初始化器参数周围的额外括号 这里。否则,这个表达式会做出与众不同的事情 可能会在跟随中得到一些奇怪的警告或错误 声明。考虑在没有额外括号的情况下编写语句:
std::deque<int> c(std::istream_iterator<int>(std::cin),
std::istream_iterator<int>());
在这种情况下,c声明一个返回类型为的函数 双端队列。它的第一个参数是istream_iterator类型 名称为cin,其第二个未命名参数的类型为“function” 不带参数返回istream_iterator。“这个结构 在语法上有效地作为声明或表达式。所以, 根据语言规则,它被视为声明。额外的 括号强制初始化程序不匹配a的语法 声明。
我可以看到为什么带有额外括号的那个不被认为是函数声明,但是
我不知道是什么会使一个没有成为函数声明?因为它有(std::cin)
左右的括号,据我所知,变量可能没有带括号的名字?
我错过了什么吗?
答案 0 :(得分:5)
你读过的教程是错误的。这样:击>
std::deque<int> c(std::istream_iterator<int>(std::cin), std::istream_iterator<int>());
无法解析为函数声明,因为std::cin
不能是参数的名称。如果您删除了std
限定符:
std::deque<int> c(std::istream_iterator<int>(cin), std::istream_iterator<int>());
然后你得到一个功能声明。
[...]据我所知,变量可能没有带括号的名字?
括号不是名称的一部分。你可以把它们放在那里,你喜欢多少:
int ((((((a)))))) = 12345; // valid code!
a++; // the variable is named 'a'
答案 1 :(得分:3)
如果语句可以解析为函数原型或带构造函数参数的变量声明,则函数原型优先。这与大多数人的期望相反,因此它被命名为Most Vexing Parse。
答案 2 :(得分:1)
据我所知,变量可能没有带括号的名称
这是错误的假设;括号不是变量名的一部分,它们只是被忽略(在此上下文中)。
来自C ++标准( [dcl.decl] ):
声明符:
- PTR声明符
- noptr-declarator参数和限定符trailing-return-type
PTR声明符:
- noptr声明符
- ptr-operator ptr-declarator
noptr声明符:
- declarator-id attribute-specifier opt
- noptr-declarator parameters-and-qualifiers
- noptr-declarator [常量表达式 opt ] 属性说明符 opt
- ( ptr-declarator )
和( [dcl.fct] ):
参数声明子句:
- parameter-declaration-list opt ... opt
- 参数声明列表, ...
参数声明列表:
- 参数声明
- 参数声明列表,参数声明
参数声明:
- attribute-specifier opt decl-specifier-seq declarator
- attribute-specifier opt decl-specifier-seq declarator = assignment-expression
- attribute-specifier opt decl-specifier-seq abstract-declarator opt
- attribute-specifier opt decl-specifier-seq abstract-declarator opt = assignment-expression
希望您可以按照这些语法定义来查看确实允许使用括号,但如果没有,请询问,我会尝试澄清。