为什么cout打印“ 2 + 3 = 15”?在这段代码中? [英] Why does cout print "2 + 3 = 15" in this snippet of code?

查看:62
本文介绍了为什么cout打印“ 2 + 3 = 15”?在这段代码中?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为什么下面程序的输出是什么?

Why is the output of the below program what it is?

#include <iostream>
using namespace std;

int main(){

    cout << "2+3 = " <<
    cout << 2 + 3 << endl;
}

产生

2+3 = 15

而不是预期的

2+3 = 5






这个问题已经经历了多个关闭/重新打开周期。


This question has already gone multiple close/reopen cycles.

在投票关闭之前,请考虑<关于此问题的href = https://meta.stackoverflow.com/questions/342113/typo-which-leads-to-a-very-interesting-analysis>此元讨论。

Before voting to close, please consider this meta discussion about this issue.

推荐答案

无论是有意还是无意,您在末尾都有<< 第一条输出行,您可能的意思是; 。因此,您基本上拥有

Whether intentionally or by accident, you have << at the end of the first output line, where you probably meant ;. So you essentially have

cout << "2+3 = ";  // this, of course, prints "2+3 = "
cout << cout;      // this prints "1"
cout << 2 + 3;     // this prints "5"
cout << endl;      // this finishes the line

所以问题归结为:为什么 cout<< cout; 打印 1

So the question boils down to this: why does cout << cout; print "1"?

这可能是令人惊讶的,微妙。 std :: cout 通过其基类 std :: basic_ios 提供某个类型转换运算符,旨在在布尔上下文中使用,例如

This turns out to be, perhaps surprisingly, subtle. std::cout, via its base class std::basic_ios, provides a certain type conversion operator that is intended to be used in boolean context, as in

while (cout) { PrintSomething(cout); }

这是一个非常糟糕的示例,因为很难使输出失败-但 std :: basic_ios 实际上是输入流和输出流的基类,对于输入来说,它更有意义:

This is a pretty poor example, as it's difficult to get output to fail - but std::basic_ios is actually a base class for both input and output streams, and for input it makes much more sense:

int value;
while (cin >> value) { DoSomethingWith(value); }

(在流结束时退出,或者当流字符不构成有效字符时退出循环

(gets out of the loop at end of stream, or when stream characters do not form a valid integer).

现在,此转换运算符的确切定义在标准的C ++ 03和C ++ 11版本之间已更改。在旧版本中,它是 operator void *()const; (通常实现为 return fail()?NULL:this; ),而在较新的版本中,它是显式运算符bool()const; (通常简单地实现为 return!fail(); )。这两个声明在布尔上下文中都可以正常工作,但是在(错误)在此类上下文之外使用时的行为会有所不同。

Now, the exact definition of this conversion operator has changed between C++03 and C++11 versions of the standard. In older versions, it was operator void*() const; (typically implemented as return fail() ? NULL : this;), while in newer it's explicit operator bool() const; (typically implemented simply as return !fail();). Both declarations work fine in a boolean context, but behave differently when (mis)used outside of such context.

尤其是在C ++ 03规则下, cout<< cout 将解释为 cout<< cout.operator void *()并打印一些地址。根据C ++ 11规则, cout<< cout 根本不应该编译,因为运算符被声明为 explicit ,因此不能参与隐式转换。实际上,这是进行此更改的主要动机-防止不必要的代码编译。符合这两个标准的编译器都不会生成打印 1 的程序。

In particular, under C++03 rules, cout << cout would be interpreted as cout << cout.operator void*() and print some address. Under C++11 rules, cout << cout should not compile at all, as the operator is declared explicit and thus cannot participate in implicit conversions. That was in fact the primary motivation for the change - preventing nonsensical code from compiling. A compiler that conforms to either standard would not produce a program that prints "1".

显然,某些C ++实现允许混合和匹配编译器和库,从而产生不一致的结果(引用@StephanLechner:我在xcode中找到了一个设置,该设置会产生1,而另一个设置会产生一个地址:语言方言c ++ 98结合使用标准库libc ++(具有c ++ 11支持的LLVM标准库)可生成1,而将c ++ 98与libstdc(gnu c ++标准库)结合可生成地址;)。您可以使用不理解 explicit 转换运算符(C ++ 11中的新功能)的C ++ 03风格的编译器,并结合使用C ++ 11-样式库,将转换定义为运算符bool()。通过这种混合, cout<< cout 解释为 cout<< cout.operator bool(),而这只是 cout<< true 并显示 1

Apparently, certain C++ implementations allow mixing and matching the compiler and the library in such a way that produces non-conforming outcome (quoting @StephanLechner: "I found a setting in xcode which produces 1, and another setting that yields an address: Language dialect c++98 combined with "Standard library libc++ (LLVM standard library with c++11 support)" yields 1, whereas c++98 combined with libstdc (gnu c++ standard library) yields an address;"). You can have a C++03-style compiler that doesn't understand explicit conversion operators (which are new in C++11) combined with a C++11-style library that defines the conversion as operator bool(). With such a mix, it becomes possible for cout << cout to be interpreted as cout << cout.operator bool(), which in turn is simply cout << true and prints "1".

这篇关于为什么cout打印“ 2 + 3 = 15”?在这段代码中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆