"cout << x"和"cout.operator<<(x)"和"operator(std::cout, x)"之间的区别?
Difference between `cout << x` and `cout.operator<<(x)` and `operator(std::cout, x)`?
这与差异-tween-cout-x和cout-operator-x问题有关,但仍然有点不同。。。
#include <iostream>
int main(){
std::cout << "hello" << std::endl;
std::cout.operator<<("hello2");
std::cout.operator<<(std::endl);
operator<<(std::cout, "hello3");
// operator<<(std::cout, std::endl);
return 0;
}
Q1:为什么std::cout.operator<<("hello2");
有效
从SO的其他答案来看,我希望编译器会抱怨,因为operator<<
是一个自由函数,而不是cout
的成员。然而,在我的系统上,它会打印"0x10d54df31"。而且,更奇怪的是,下面的行正确地执行了std::endl
。
Q2:为什么operator<<(std::cout, std::endl);
不起作用
我知道std::endl
是一个函数,但(对我来说)hello3输出有效,而"std::endl"却无效,这似乎很奇怪。相反,编译器抛出一个错误:
main.cpp:10:4: error: no matching function for call to 'operator<<'
operator<<(std::cout, std::endl);
Q3:第一个std::cout << "hello1" << std::endl;
怎么能用operator<<(...)
的形式写
如果前两个问题已经得到回答,那么这可能已经涵盖了。这就是这个学习练习的重点,所以明确地问它似乎是明智的。
运算符可以用不同的方式实现,特别是左手边是您类型的operator<<
,它可以实现为自由函数或该左手边类型的成员函数。
虽然您必须将ostream& operator<<(ostream&, MyType const&)
实现为一个自由函数(因为MyType
不是左手边),但库实现可以选择*为std::ostream
类型中的一些基本类型实现operator<<
(这实际上是一个模板的特定实例化,我试图忽略细节)。
编辑:在与标准进行检查后,这是不正确的:
这就是您在代码中注意到的,使用
const char*
的重载被实现为ostream
(basic_ostream<char,char_traits<char>
)的成员
重载操作器被实现为成员函数(Q2),如果使用显式调用成员运算符(Q1)的语法,则会选择从const char*
到const void*
的隐式转换。对于第三季度,答案是:
operator<<(std::cout, "Hello").operator<<(std::endl);
*实现实际上并不是可以自由选择的,因为标准要求签名。
operator<<
的一些重载是类成员,其他则不是。
在C++03中,这造成了一些令人困惑的调用场景,因为对非const
(非成员的参数)的引用不能绑定到右值,但在C++11中,通过引入右值引用参数重载,至少解决了一个这样的问题。
因此,调用compile与否在很大程度上也取决于C++标准版本,即C++03或C++11。
std::ostream
中定义了一组成员输出运算符。回想起来,这可能是一个错误,但当IOStreams第一次创建时,我认为这实际上是必要的。这些成员运算符包括采用函数指针的重载,这意味着您需要对这些重载使用成员表示法。使用C字符串的运算符是非成员重载,即,您需要使用非成员函数调用表示法来获得C字符串重载。当您用char const*
调用成员运算符时,char const*
将转换为有成员输出运算符的void const*
。
您的问题可以分解为成员函数和非成员函数。
具有13.5.2二进制运算符
应实现二进制运算符通过具有一个参数的非静态成员函数(9.3)或通过具有两个参数的非成员函数。因此,对于任何二进制operator@,x@y可以解释为x.operator@(y)或运算符@(x,y)。如果运算符函数的两种形式都已则13.3.1.2中的规则确定,使用解释。
最好省略13.3.1.2的引用,即成员函数(运算符)。
行"std::cout<lt;"你好"<lt;std::endl;'涉及非成员职能。每个"std::cout.operator"都是一个显式成员函数调用。
- Q1是成员运算符<lt;(const void*)
- Q2没有成员执行功能
- Q3不可能
- 请解释这句话(cout<<1+int((a<b)^((b-a)&1) )<<endl
- 呼叫运营商<<临时
- std::cout.imbue()多重调用
- 如何在C++中用std::cout正确显示带十六进制的字符串文本
- 为什么在C的循环中使用printf的Rust代码不显示输出,而在C++的循环中显示std::cout
- 如何防止clang格式在流运算符调用之间添加换行符<<
- <<操作员在下面的行中工作
- 为什么我应该在异常处理中使用std::cerr而不是std::cout
- 在作为静态成员包含在另一个类中的类的构造函数中使用 cout
- 在 COUT 语句中使用 COUT 调用函数
- GCC 4.8.2 自动矢量化由于 cout 而失败
- std::cout输出int时出现编译错误
- 为什么COUT在朋友函数中不起作用,该功能超载了操作员&lt;&lt;这是一个iStream运算符
- C++标准::cout和<<操作员,优先级
- 以x的倍数填充前导零,使用std::cout<<std::十六进制
- 错误:没有匹配'运算符<<"在'std::cout
- 过载<<比如cout错误
- cout & lt; & lt;“text"只在部分时间显示
- 如何显示/打印字符串对象?cout & lt; & lt;Int工作,count <<字符串
- 我怎样才能到达cout<<"排序:";;当C++中没有输入数字时