问题就在标题中;我确定有一个逻辑性的解释,但现在我却被难住了!
根据《C++设计与演化》第8.3.1节:
提供输出运算符而不是命名的输出函数的想法是由Doug McIlroy通过与UNIX shell中的I/O重定向运算符(>、>>、|等)进行类比而提出的。
[...]
考虑了几个操作符用于输入和输出操作: 赋值运算符被认为可用于输入和输出,但它绑定方式不正确。例如,
cout=a=b
将被解释为cout=(a=b)
,大多数人似乎更喜欢输入运算符与输出运算符不同。 尝试使用<
和>
操作符,但是“小于”和“大于”的含义深深植根于人们的思想中,以至于新的I/O语句在实际使用中几乎无法阅读(但对于<<
和>>
则不是这种情况)。此外,'<'在大多数键盘上刚好在','上方,因此人们会编写如下表达式:cout < x , y, z;
对于这个问题,要提供好的错误信息并不容易。
也许是因为它看起来类似于Unix的追加操作,因为你实际上是在输入/输出流中添加内容?
例如:
echo“foo”>> bar
sendmail -f test@domain.com << myemail.txt
(从Zac Howland那里窃取了输入示例)
->
已经有了现有的含义,符号对<-
也是如此。 - Ben Voigt来自《C++编程语言》作者Stroustrup的话:
重载运算符
<<
以表示“放置”会给出更好的记法,使程序员可以在单个语句中输出一系列对象。但是为什么是
<<
?无法发明新的词汇。赋值运算符既适用于输入也适用于输出,但大多数人似乎更喜欢使用不同的运算符进行输入和输出。此外,=绑定错误;即cout=a=b意味着cout=(a=b)而不是(cout=a)=b。我尝试了运算符<
和>
,但是“小于”和“大于”的含义在人们的思维中已经根深蒂固,新的I/O语句在实际使用中几乎无法阅读。
std::cout << foo() << bar() << std::eol;
这并不意味着在调用bar
之前会先调用foo
。
在C++17中,顺序问题已经被“修复”。现在,对于<<
和>>
运算符,计算顺序被指定为从左至右。在C++中仍然存在一些未指定顺序的地方(甚至是不存在顺序,这意味着计算可能会交错进行),但现在一些常见情况的行为方式变得可预测且具有可移植性,请参见此答案。
foo()
被调用之前保证会调用bar()
...他们编写这样的代码s << header() << body() << footer();
其中body()
计算了在footer()
中使用的一些总数。这种错误对于函数参数来说不太常见。 - 6502setw
和 setfill
这样可怕函数的库)。 - 6502如果你把cin
看作是键盘,cout
看作是显示器,那么你输入的内容会被存储到变量中。
cin>>var;
cout<<var;
>>
和<<
只是操作符,您可以为自己的类实现自己的>>
和<<
。我想“某人”选择它们的原因可能是:a)它们类似于shell文件操作;b)重用现有的运算符,因为没有必要创建新的运算符。
std::cout << "Hello" << ' ' << 4 << 2;
按照你的预期进行评估:首先是"Hello"
,然后是' '
,最后是4
和2
。可以承认的是,加法运算符operator+
也从左到右关联。但是,具有从左到右结合性的该运算符和其他运算符已经具有不同的含义。
在这个上下文中,它们不是位运算符,而被称为插入和提取运算符。
http://www.cplusplus.com/doc/tutorial/basic_io/
这些仅用于视觉解释。如果您学习开发自己的流和运算符重载,那么您甚至可以使用+进行输入,-进行输出 :)
这个答案虽然不是很令人满意,但是是正确的:它们并不是位运算符。
操作符的含义取决于左侧出现的数据类型。在cin和cout(以及其他流类型)中,<<和>> 操作符将值移入和移出流中。如果左操作数是整数,则该操作是您已经了解的C中的位运算。
操作符的含义没有固定,尽管其优先级是固定的。
>>
和<<
分别用于输入流和输出流,因为输入流表示数据进入程序的流动,而输出流表示数据从程序中流出。由于这些插入运算符看起来像方向运算符(显示数据流动的方向),所以>>
被选用作输入流,<<
被选用作输出流。int Num1;
cin >> Num1;
>>
表示将数据流向程序中的变量(在程序中声明),这意味着数据的流向由输入流(此处为cin
)完成。cout
。int Num2 = 5;
cout << Num2;
<<
表示数据从程序中流出(由于Num2
是程序的一部分),这是输出流的工作。
read()
和write()
这样的函数怎么处理?我认为用户自定义运算符应该具有与内置运算符类似的语义,例如+
可以用于添加复数或几何向量。但是ostream::operator<<
与位移操作无关。一些早期的 C++ 设计决策现在被认为存在问题,例如自动生成复制构造函数如果存在析构函数,则不一定需要在operator<<
的选择中体现出逻辑相关性。 - Philipp