关于istream_iterator<int>(cin)和istream_iterator<int>()的一点分析
最近在看STL,其中讲到容器这一部分的时候,有以下两个式子,有点疑惑:
deque<int> c(istream_iterator<int>(cin), istream_iterator<int>()); () //函数声明
deque<int> c((istream_iterator<int>(cin)), (istream_iterator<int>())); () //定义一个容器
式子原本的含义都是要定义一个容器,容器的内容从标准输入获取。
这里主要分析下两个式子产生这种区别的原因:
1、式子(1),我们知道,c++中定义一个变量可以是:
<pre name="code" class="cpp">int a; //标准的定义,在声明式中也可以作为参数类型声明
int(a); //另一种定义,实际就是利用了括号的分割作用,与上一种本质相同
int(); //定义一个匿名的变量,在声明式中是作为一个函数声明,形同int (*)()
int(); //定义一个匿名变量,并用1初始化</pre>
注意上面几种形式,尤其是第三种形式是理解上述两个式子区别的关键。
好了,这样子的话,表达式中,
- istream_iterator<int>(cin)既可以理解为定义一个用cin去初始化的匿名istream_iterator<int>变量,也可以理解为定义一个知名变量,即istream_iterator<int> cin;
- istream_iterator<int>()可以理解为定义一个默认初始化的匿名变量,也可以理解为声明一个函数指针,即istream_iterator<int> (*)();
既然这样的话,对于(1)式,就用两种理解方式:
- 一是可以理解为c是一个函数声明,其参数是一个istream_iterator<int>变量,一个函数指针istream_iterator<int> (*)(),返回值是deque<int>;
- 二是可以理解为定义一个deque<int>的变量c,用两个iterator迭代器来对变量c进行初始化,因为deque有一种初始化方式就是deque<T> c(begin, end);
在这种情况下,编译器默认优先将(1)式理解为函数声明。
2、那么,为什么在(2)式中将参数加上括号后就可以避免这种歧义呢?
在c++中,函数的声明形式必须是 returnType fun(type1, type2, ...),对于returnType fun((type1),( type2), ...)的形式,是不能作为函数声明来通过编译的,由此,在(2)式中将参数都加上括号后,即可自动消除表达式是函数声明的可能,所以语义也就很清晰了,即定义一个容器。
由此得到的结论是:
编译器总是优先看作声明,其次看作表达式。
关于istream_iterator<int>(cin)和istream_iterator<int>()的一点分析的更多相关文章
- [C/C++] 输入函数getline(cin,str) 与cin.getline(str,int)区别
cin.getline()函数是处理数组字符串的,其原型为cin.getline(char * , int),第一个参数为一个char指针,第二个参数为数组字符串长度. getline(cin,str ...
- C++中int *p[4]和 int (*q)[4]的区别
这俩兄弟长得实在太像,以至于经常让人混淆.然而细心领会和甄别就会发现它们大有不同. 前者是指针数组,后者是指向数组的指针.更详细地说. 前: 指针数组;是一个元素全为指针的数组.后: 数组指针;可以直 ...
- C语言复杂声明-void (*signal(int sig, void (*handler)(int)))(int);
问题提出 请分析此声明:void (*signal(int sig, void (*handler)(int)))(int); 求解过程 在对上面的例子作分析之前,我们需要了解C语言的声明优先级,&l ...
- 编写Java应用程序。首先,定义描述学生的类——Student,包括学号(int)、 姓名(String)、年龄(int)等属性;二个方法:Student(int stuNo,String name,int age) 用于对对象的初始化,outPut()用于输出学生信息。其次,再定义一个主类—— TestClass,在主类的main方法中创建多个Student类的对象,使用这些对象来测 试Stud
package zuoye; public class student { int age; String name; int stuNO; void outPut() { System.out.pr ...
- const int * p 和 int const * p 和 int * const p 的区别
首先注意,const int * p 和int const *p 是一样的,并且不管是不是*p,即使const int i和int const i也是一样的,所以我们接下来只讨论int const * ...
- (int &)a 和(int)a
[cpp] view plain copy float a = 1.0f; cout < < (int)a < < endl; cout < < ...
- int * const 与 const int * 的区别
type * const 与 const type * 是在C/C++编程中特别容易混淆的两个知识点,现在就以 int * const 和 const int * 为例来简略介绍一下这两者之间的区别. ...
- open_clientfd(char* hostname,int port)和open_listenfd(int port)
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h&g ...
- 如何理解这段代码:void (*signal (int sinno,void(*func)(int)))(int)
void (*signal (int sinno,void(*func)(int)))(int) 先来看void(*func)(int) 这里的意思是声明一个函数指针func,它的参数类型为int ...
随机推荐
- 字符缓冲流BufferedWriter BufferedReader
//字符缓冲流主要用于文本数据的高速写入 package cn.lijun.demo1; import java.io.BufferedReader; import java.io.FileNotFo ...
- qml: 以鼠标为中心进行放缩;
import QtQuick 2.9 import QtQuick.Window 2.2 import QtQuick.Controls 2.2 Window { visible: true widt ...
- Mesos初体验-Mesos优势
一.Mesos优势 1.Mesos的核心是分布式集群资源分配,不负责任务调度,因而Mesos可以和其他集群协同工作 2.Mesos主要实现了分布式集群的管理系统中的资源分配功能,其他功能主要靠额外的组 ...
- 3D转换(位置)+过渡+透视
效果如图: html代码: <div class="door"> <div class="in"><div> </di ...
- VirtualBox使用入门
VirtualBox使用入门 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 能玩虚拟机的人多少是懂点运维的,因此我就不跟大家介绍啥事虚拟化了.关于虚拟化产品大家用的应该也都大同小异 ...
- 本地服务器上挂载A目录到B目录
原因: 由于某个分区满了,切磁盘无法扩大分区空间,但是项目依赖该分区,需要继续像该分区存储文件,此时其他分区还有很大的空间,使用挂载的方式,在有空间的分区创建新目录,将新目录挂载到源目录下即可. 执行 ...
- ASP.NET新建解决方案和网站
新建解决方案和网站 1.打开visual studio,选择新建项目,然后选择解决方案. 2.解决方案建好之后,右键点击解决方案选择新建网站.注意,路径.我在solution1文件夹下面又建了一个si ...
- oracle里实例和数据库之间的关系
一个数据库服务器上可以装几个数据库它们都是用sid来标志,例如orcl1,orcl2,orcl3等等,一个数据库如orcl1中可以有多个实例吗? Oracle数据库,实际上应该是说,我们使用的是Ora ...
- 设计模式---数据结构模式之迭代器模式(Iterate)
一:概念 迭代模式是行为模式之一,它把对容器中包含的内部对象的访问委让给外部类,使用Iterator(遍历)按顺序进行遍历访问的设计模式. 在应用Iterator模式之前,首先应该明白Iterator ...
- sqlalchemy外键和relationship查询
前面的文章中讲解了外键的基础知识和操作,上一篇文章讲解了sqlalchemy的基本操作.前面两篇文章都是作为铺垫,为下面的文章打好基础.记得初一时第一次期中考试时考的不好,老爸安慰我说:“学习是一个循 ...