C++ << 相同类型的运算符重载
C++ <<operator overloading with same type
我正在编写一种方法来打印 std::cout
中的一些空格,我知道还有其他方法可以使用标准库来实现相同的 objective。无论如何,我使用 typedef
来存储空格数和 <<
运算符的重载。但是根本没有调用我的重载,因为我的 typedef
被解释为无符号整数。
那么我如何告诉编译器调用我的函数呢?
class MyClass {
private:
typedef unsigned int space_type;
public:
std::ostream& operator<< (std::ostream& _os, space_type _n_spaces) {
for (int _C = 0; _C < _n_spaces; _C++)
_os << " ";
return _os;
}
void PrintNumbers(char _a, char _b) {
space_type spaces = 5;
std::cout << _a << spaces << _b << std::endl;
}
}
int main () {
MyClass class_instance;
class_instance.PrintNumbers('K', 'X');
std::cin.get();
return 0;
}
这是预期的输出:
K X
这是我获得的输出:
K5X // 5 is interpreted as an unsigned int, so my overloaded function
// isn't called, instead is called the std overloading with unsigned int
Typedef 不创建新类型,它只是创建现有类型的别名。可能你可以使用这样的东西:
struct SpaceType {
int space_cnt;
};
...
std::ostream& operator<< (std::ostream& _os, SpaceType _n_spaces) {
for (int _C = 0; _C < _n_spaces.space_cnt; _C++)
_os << " ";
return _os;
}
...
SpaceType spaces = { 5 };
std::cout << _a << spaces << _b << std::endl;
由于您将 space_type
定义为 别名 (即 typedef)而不是类型,因此它与 int
没有区别,并且如果您试图重载 operator(std::ostream&, int)
.
,编译器将发出错误消息
但是你正在做的是定义一个 class 成员:
std::ostream& operator<< (std::ostream& _os, space_type _n_spaces)
当您将运算符定义为 class 成员时,运算符的第一个参数(隐含地)是 class 的一个实例。所以原则上,只能调用:
MyClass m;
m << ???
但这里有一个问题:使用中缀表示法调用的运算符函数只能有两个参数,对于成员运算符函数,第一个参数是隐式的。 m << x
只能由MyClass::operator<<(decltype(x))
实现。
简而言之,您只能使用非成员 operator<<
实现此功能,并且该重载的第二个参数必须是用户类型。所以以下将正常工作:
struct space_t {
unsigned x;
space_t(unsigned x) : x(x) {}
operator unsigned() const { return x; }
};
std::ostream& operator<< (std::ostream& os, space_t n) {
for (unsigned i = 0; i < n; ++i) os << " ";
return os;
}
在 ideeone
上查看
我正在编写一种方法来打印 std::cout
中的一些空格,我知道还有其他方法可以使用标准库来实现相同的 objective。无论如何,我使用 typedef
来存储空格数和 <<
运算符的重载。但是根本没有调用我的重载,因为我的 typedef
被解释为无符号整数。
那么我如何告诉编译器调用我的函数呢?
class MyClass {
private:
typedef unsigned int space_type;
public:
std::ostream& operator<< (std::ostream& _os, space_type _n_spaces) {
for (int _C = 0; _C < _n_spaces; _C++)
_os << " ";
return _os;
}
void PrintNumbers(char _a, char _b) {
space_type spaces = 5;
std::cout << _a << spaces << _b << std::endl;
}
}
int main () {
MyClass class_instance;
class_instance.PrintNumbers('K', 'X');
std::cin.get();
return 0;
}
这是预期的输出:
K X
这是我获得的输出:
K5X // 5 is interpreted as an unsigned int, so my overloaded function
// isn't called, instead is called the std overloading with unsigned int
Typedef 不创建新类型,它只是创建现有类型的别名。可能你可以使用这样的东西:
struct SpaceType {
int space_cnt;
};
...
std::ostream& operator<< (std::ostream& _os, SpaceType _n_spaces) {
for (int _C = 0; _C < _n_spaces.space_cnt; _C++)
_os << " ";
return _os;
}
...
SpaceType spaces = { 5 };
std::cout << _a << spaces << _b << std::endl;
由于您将 space_type
定义为 别名 (即 typedef)而不是类型,因此它与 int
没有区别,并且如果您试图重载 operator(std::ostream&, int)
.
但是你正在做的是定义一个 class 成员:
std::ostream& operator<< (std::ostream& _os, space_type _n_spaces)
当您将运算符定义为 class 成员时,运算符的第一个参数(隐含地)是 class 的一个实例。所以原则上,只能调用:
MyClass m;
m << ???
但这里有一个问题:使用中缀表示法调用的运算符函数只能有两个参数,对于成员运算符函数,第一个参数是隐式的。 m << x
只能由MyClass::operator<<(decltype(x))
实现。
简而言之,您只能使用非成员 operator<<
实现此功能,并且该重载的第二个参数必须是用户类型。所以以下将正常工作:
struct space_t {
unsigned x;
space_t(unsigned x) : x(x) {}
operator unsigned() const { return x; }
};
std::ostream& operator<< (std::ostream& os, space_t n) {
for (unsigned i = 0; i < n; ++i) os << " ";
return os;
}
在 ideeone
上查看