为什么c++的iostream总是左赋值?
Why are C++ iostreams always left-hand assigned?
我正在学习c++,从来没有处理过流。我希望符号是:
std::cout << "foo";
char foo << std::cin;
我确信它是std::cin >> foo
有一个很好的理由。这是什么?
这与<<和>>操作符。
它们最初只用于左结合的位移位。操作符的关联性在重载时保持不变(否则,代码将无法解析):
如果你做了
int a, b ;
a << b << cin
你会得到
(a << b) << cin
位移位和输入
a << b
和a >> b
都是:
operator<<(a,b)
和
operator>>(a,b)
(或等价的成员函数)。
也就是说,它们只是对特定函数的调用。恰好c++标准库重载operator<<
来执行ostream
s的输出流,重载operator>>
来执行istream
s的输入流。
这些函数只有在流位于左边时才被重载。
这个决定有两个原因。首先是符号的简单性(也就是说,由于只有一种对操作数排序的方式,因此任何特定代码的含义都不那么模棱两可,并且在扩展标准库以支持额外的类时,也不需要实现大量不同的重载)。第二,<<
和>>
是左结合的,所以:
int a, b;
a << b << cin;
将成为:
(a << b) << cin;
:
int a, b;
cin >> b >> a;
正确的是:
(cin >> b) >> a;
所以你将被迫按照上帝的意愿把控制台放在左边!:)
实际上与操作符重载有关。如果你刚刚学习c++,你可能还没有涉及到这一点,所以把我要说的东西放在"我以后会得到的东西"下面。
c++位于C之上。在C中,<<
和>>
只是位移位运算符。在c++中可以更多。std:cout << foo
不是C,它是c++。之所以是c++,是因为std::cout
对象重载了<<
操作符,以表示除位移位之外的其他含义。
换句话说,<<
只表示将foo
发送给cout
,因为cout
说这就是它的意思。<<
实际上是类cout
上的一个函数。
就好像你说的是std::cout->sendThatToMe(foo)
。
在整个事件中,foo
只是一个倒霉的参数,它对<<
的含义没有发言权。这就是为什么你不能用另一种方式去做。如果你这样做了,就好像你在说:
foo->sendMeToThat( std::cout).
如果你把这个函数(实际上是>>
操作符)添加到你可能想要发送到控制台的每个臭对象上,就可以工作了。哦,祝你好运,用原语完成它。
所以,虽然我认为有很好的风格原因,想要保持控制台的东西在左边,实际上是一个技术原因,它必须这样做。这是因为被重载的操作符已经是左结合的了。在旧的C时代,它们被用来移动比特。重载它们不提供改变它们的结合性的机会。
这就是他们应该工作的方式。我认为这样做是为了清楚地区分输入操作(>>)和输出操作(<<)
。如果您以这种奇特的方式重载<<
操作符(正如Captain Obvious在注释中建议的那样):
template<typename T>
std::istream& operator<<( T& data , std::istream& is )
{
is >> data;
return *this;
}
如果操作是输入还是输出,则不太清楚(使用std::cin std::cout
很容易,但是关于两个名为file1
和file2
的流,一个用于读取,一个用于写入):
a << std::cin;
std::cout << a;
a << file;
file << a;
- 为"adjacent"变量赋值时出现问题
- C++中的赋值发生,尽管右侧出现异常
- 用C++中的sscanf赋值
- 为std::string的某个索引赋值
- 重载Singly Linked List中的赋值运算符
- 为什么我必须在C++中添加一个赋值符号来声明一个数组
- gtest_使用setargpointee在函数中赋值
- 非常量变量只读位置的赋值
- 使用赋值运算符重载从类中返回jobject
- C++数据文件、数组和计算赋值
- 为什么在使用转换构造函数赋值后调用C++类的析构函数?
- 全局作用域中函数指针的赋值
- 错误:在为指针赋值时,void值没有被忽略
- 标准库类型的赋值运算符的引用限定符
- 关于 c++ 函数中指针赋值的简单问题
- 复制构造函数、赋值运算符C++
- 标准::变体的赋值运算符
- cin >> int 给定一个字符串将 int 赋值为 0
- if 子句中的赋值不起作用
- 复制包含C++所有元素的对象!(构造函数和赋值,最佳实践?