我正在尝试理解C ++中的基础过程,它允许我们在C ++中形成以下表达式:
cout << "Hello," << "World" << a + b;
根据我的理解,首先,insert运算符将ostream对象cout
和字符串文字"Hello"
作为操作数,表达式返回cout
类型,因此{{1}现在是下一个字符串文字的类型,最后也是表达式cout
的类型。
我无法理解这个过程的技术细节,我理解参与是否允许我们这样做?
答案 0 :(得分:5)
你可以认为<<
运算符在stdio函数方面实现了类似的东西(现在只考虑字符串):
ostream &operator <<(ostream &stream, const string &data)
{
fprintf(stream, "%s", data.c_str());
return stream;
}
此代码与写入的完全不同,因为fprintf
的第一个参数应该是FILE*
,而不是ostream
。但那并不重要。与您的问题相关的重要部分是最后的return stream;
,它返回您传递回调用者的相同流。有了它,你可以将呼叫链接在一起。
表达式
cout << a << b;
与
相同(cout << a) << b;
(cout << a)
的结果再次为cout
(加上实际打印a
值的副作用)。
答案 1 :(得分:5)
根据我的理解,首先,插入运算符将ostream对象cout和字符串文字“Hello”作为操作数,表达式返回一个cout类型...
到目前为止很好......
因此cout现在是下一个字符串文字的类型,最后也是表达式a + b的类型。
我不确定你在这里想说什么。如果根据优先级对运算符进行分组,它可能会有所帮助:
(((cout << "Hello,") << "World") << (a + b));
第一次调用operator<<
时,其参数为cout
和"Hello"
,正如您所说。返回cout
。然后,第二次,参数是cout
(前一个的结果)和"World"
。然后,第三次,参数为cout
,结果为a + b
。
也许它有助于进一步使用(技术上不正确的,参见@DavidRodríguez-dribeas的注释)函数调用语法重写代码:
operator<<(operator<<(operator<<(cout, "Hello,"), "World"), a + b);
因为每次调用operator<<
它都会返回cout
,每次调用的第一个参数将是cout
。
答案 2 :(得分:1)
班次操作员<<
从左到右分组。所以陈述
cout << "Hello," << "World" << a + b;
对应表达式
( ( ( cout << "Hello," ) << "World" ) << a + b );
在表达
中cout << "Hello,"
使用重载的运算符函数&lt;&lt;对于std::basic_ostream
类型的左操作数和类型为const char *
template<class charT, class traits>
basic_ostream<charT,traits>& operator<<(basic_ostream<charT,traits>&, const charT*);
它返回对basic_ostream
的引用。
std::cout
被定义为basic_iostream<char>
执行后
cout << "Hello,"
您可以参考std::cout
。而这又成为表达式的左操作数
cout << "World"
并最后返回上述表达式的引用,因为它是表达式的左操作数
cout << a + b
我认为a和b是一些算术类型。此表达式是对std::basic_ostream
和此算术类型的重载运算符函数的调用。
当此运算符返回std_basic_ostream
或更准确地返回std::cout
时,它将成为完整表达式的返回类型。