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

How to implement C++ stream manipulator endl correctly?

我正在尝试为我的 stream class 实现一个操纵器。我对操纵器了解不多,但我认为我做的一切都是对的。代码的相关部分如下:

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)。有什么想法吗?

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

您可能打算添加一个重载

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

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

因为你的 endl 既不是 bool 也不是 const char[] (它是一个自由函数),它被隐式转换为 bool(true) 并调用以下函数:

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](

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