C++ <<与相同类型的操作符重载

问题描述:

我正在写一个方法来打印std::cout中的一些空格,我知道还有其他方法使用标准库来实现相同的目标。无论如何,我用typedef来存储空间的数量和<<运算符的超载。但我的重载根本没有被调用,因为我的typedef被解释为unsigned int。C++ <<与相同类型的操作符重载

那么如何告诉编译器调用我的函数呢?

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 
+0

Typedef不会创建新类型,它只会创建现有类型的别名。 – kvorobiev 2015-04-04 18:52:25

,而不是一个类型,它是没有区别的int,编译器会发出如果一个错误:Possbile你可以使用这样的事情您试图超载operator(std::ostream&, int)

但是你在做什么是定义一个类的成员:

std::ostream& operator<< (std::ostream& _os, space_type _n_spaces) 

当你定义运营商级的成员,第一个参数来操作(隐含)的类的实例。因此,在原则上,只能用称为:

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

+0

但是,如果我用一个结构替换typedef,类中的重载函数正常工作。 – Michele 2015-04-04 19:56:09

+0

@Michele:你的意思是这样的:http://ideone.com/1y9Akx(但是这给出了预期的编译错误)。 – rici 2015-04-04 20:03:40

+0

随着重载使用的关键字朋友,它的作品 – Michele 2015-04-04 20:07:30

的typedef并不创建新的类型,它只是创建现有类型的别名。既然你定义space_type作为别名(即类型定义)

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; 
+0

我知道这个解决方案,但是我想避免为此使用struct – Michele 2015-04-04 19:12:19

+0

@Michele:为什么?没有真正的成本。 – rici 2015-04-04 19:16:16

+0

因为我觉得我正在浪费一些代码来写下结构和实例,只是为了一堆空间。无论如何,如果没有解决方案,那没关系。 – Michele 2015-04-04 19:23:27

我RICI同意。完美解释。