如何正确实现C ++流操纵器endl?

时间:2017-02-09 17:44:38

标签: c++ operator-overloading manipulators

我正在尝试为我的stream类实现一个操纵器。我对操纵者知之甚少,但我认为我做的一切都是正确的。代码的相关部分如下:

class stream
{
public:
    stream& operator<<(bool b) { // send bool value and return *this; }
    stream& operator<<(const char str[]) { // send string and return *this }
}; 

inline stream& endl(stream& s) 
{
    return s << "\r\n";
}


class stream stream;

int main()
{
    stream << endl;
}

我不知道我做错了什么,但是编译器调用endl而不是调用stream::operator<<(bool)。有什么想法吗?

2 个答案:

答案 0 :(得分:5)

看到stream << endl;编译器必须从您提供的operator <<中选择一个重载。 endl不能转换为const char *,但可以转换为bool,这就是你得到的。

你可能想要添加一个重载

stream& operator<<(stream &(*function)(stream &)) {
   return function(*this);
}

正确处理函数指针的class stream内部。

答案 1 :(得分:1)

由于endl既不是bool也不是const char[](它是免费功能),因此会隐式转换为booltrue )并调用以下函数:

stream::stream& operator<<(bool b)

您可以将endl定义为特殊类型endl_t,并为其定义正确的运算符:

#include <iostream>
#include <string>
#include <array>

//Just make the operators `explicit`. See [this excellent answer on SO](http://stackoverflow.com/a/8239402/5470596).

class stream
{
public:
    stream& operator<<(bool b) { std::cout << "bool\n" ; return *this; }
    stream& operator<<(const char str[]) { std::cout << "const char[]\n" ; return *this; }
};

struct endl_t {} endl;

stream& operator<<(stream& s, endl_t)
{
    s << "\r\n";
    return s;
}


int main()
{
    stream s;
    s << endl; // prints "const char[]"
}

Live on coliru