问题描述
为什么下面程序的输出是什么?
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.
在投票关闭之前,请考虑此元讨论。
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”?在这段代码中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!