调用构造函数可以视为函数声明吗?

时间:2012-01-17 23:20:00

标签: c++ stl

接下来的几行我将来自“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)左右的括号,据我所知,变量可能没有带括号的名字?

我错过了什么吗?

3 个答案:

答案 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
  •   

希望您可以按照这些语法定义来查看确实允许使用括号,但如果没有,请询​​问,我会尝试澄清。