我正在研究重载运算符。
在<<
和double
上使用std::string
运算符之间没有区别。
int main()
{
double a = 12;
string s = "example";
operator<<(cout, a); //doesn't work
cout.operator<<(a); //works
operator<<(cout, s); //works
cout.operator<<(s); //doesn't work
}
operator<<(cout, a)
和cout.operator<<(s);
为什么不起作用?
答案 0 :(得分:6)
因为该运算符被定义为成员函数,而不是自由函数。
操作符可以通过两种方式重载,当与常规操作符语法一起使用时,这对用户是透明的。但是,使用显式语法时,必须使用特定于实际函数定义的语法。
此示例显示了实际的区别:
class Stream {
Stream& operator<<(Inside);
};
Stream& operator<<(Stream&, Outside);
对于std::string
,使用Outside
方式。对于double
,Inside
是
答案 1 :(得分:4)
您可以用两种不同的方式定义运算符,作为一个类的成员和带有两个参数的独立函数。
接受双精度值的运算符被实现为std::ostream
的成员函数,请参见cpp reference。您会注意到提供的char const*
或std::string
没有重载。这些功能separately被定义为独立功能,还有其他一些功能。
那些定义为成员的运算符(仅用于!)使用cout.operator<<(argument)
表示法,而带有两个参数的变体形式的独立运算符。
但是,如果按预期使用运算符,则所有这些差异都将被隐藏:
std::cout << whatEver;
答案 2 :(得分:2)
因为类型std :: basic_ostream&的非类运算符<<和double(或const double&)在C ++中未定义。
此类在类std :: basic_ostream中声明为采用双精度类型一个参数的运算符作为成员函数。
basic_ostream<charT, traits>& operator<<(double f);
对于类型为std :: string的对象,操作员通过以下方式声明为独立(非类成员)函数
template<class charT, class traits, class Allocator>
basic_ostream<charT, traits>&
operator<<(basic_ostream<charT, traits>& os,
const basic_string<charT, traits, Allocator>& str);
答案 3 :(得分:2)
std::basic_ostream
提供了一些<<
实现(对于基本类型)作为成员函数。对于其他类型(例如对于std::basic_string
),operator <<
被实现为自由函数。这就是标准指定的方式。
仅当您使用显式函数调用符号(如您的代码中)调用运算符时,这才是问题。使用它的自然方法是使用运算符(cout << x
),该问题不会发生,因为它可以调用成员函数和自由函数。
答案 4 :(得分:0)
您使用操作符的方式不正确。
运算符可以实现为成员函数或非成员函数。
跑步时
cout.operator <<(a);
cout << a;
cout.operator <<(s);
cout << s;
您正在调用类运算符实现;
但是当您打电话
operator<<(cout, a);
实现在哪里? o_O
工作示例测试了vc ++ 13和gcc(here)
#include <iostream>
using std::cin;
using std::cout;
using std::endl;
int main(int argc, char* argv[])
{
int number = 13;
float pi = 3.13f;
double dp = 2.23233;
cout << "number: " << number << endl;
cout << "pi: " << pi << endl;
cout << "double: " << dp << endl << endl;
cout.operator <<(number) << endl;
cout.operator <<(pi) << endl;
cout.operator <<(dp);
}
注释是否需要示例类型的成员或非成员实现。