我们如何允许在C ++中将插入操作符和其他操作符链接在一起?

时间:2014-03-02 20:03:26

标签: c++ operators

我正在尝试理解C ++中的基础过程,它允许我们在C ++中形成以下表达式:

cout << "Hello," << "World" << a + b;

根据我的理解,首先,insert运算符将ostream对象cout和字符串文字"Hello"作为操作数,表达式返回cout类型,因此{{1}现在是下一个字符串文字的类型,最后也是表达式cout的类型。

我无法理解这个过程的技术细节,我理解参与是否允许我们这样做?

3 个答案:

答案 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时,它将成为完整表达式的返回类型。