将std::endl传递给std::operator <<

3
在这个 Stack Overflow回答 中提到,std::cout << "Hello World!" << std::endl; 和以下代码等价:
std::operator<<(std::operator<<(std::cout, "Hello World!"), std::endl);

但是,当我编译上面的代码时,它无法编译!然后尝试了其他一些方法后,我发现它无法编译的原因是因为 std::endl,如果我用"\n"替换 std::endl,那么它就可以工作了。但为什么不能将 std::endl传递给 std::operator<<
或者更简单地说,std::cout<<std::endl; 是否与 std::operator<<(std::cout, std::endl); 相同?
编辑
使用 icpc test.cpp 编译时,错误消息为 error: no instance of overloaded function "std::operator<<" matches the argument list argument types are: (std::ostream, <unknown-type>) std::operator<<(std::cout, std::endl);g++ test.cpp 给出了更长的错误消息。

后一个问题可能只需要尝试那一行代码就能得到答案。而"...它无法编译!"除非你在问题中也包括错误信息,否则意义不大。 - WhozCraig
我尝试过使用 std::operator<<(std::cout, std::endl);,但无法编译通过。 - Allanqunzi
2
重载操纵符是一个成员函数,因此 std::cout.operator<<(std::endl) - David G
“std::operator <<”和“std::cout.operator <<”有什么区别?您认为在哪里可以找到关于“std::operator <<”的参考资料? - Allanqunzi
@Allanqunzi 这是成员函数调用和非成员函数调用的区别,类似于 print(x, "hi")x.print("hi")虽然运算符函数的查找方式与其他名称不同 - David G
2个回答

5
因为那里的答案有点错误。std::endl 是一个操作符函数,没有在 ostream 的独立 operator<< 定义中进行重载。它是 basic_ostream 的成员函数。
换句话说,所呈现的调用是错误的。应该是以下之一:
#include <iostream>
int main() {
    std::endl(std::operator<<(std::cout, "Hello World!"));
    std::operator<<(std::cout, "Hello World!").operator<<(std::endl);

    //of course if you pass new line as a supported type it works
    std::operator<<(std::operator<<(std::cout, "Hello World!"), '\n');
    std::operator<<(std::operator<<(std::cout, "Hello World!"), "\n");
    std::operator<<(std::operator<<(std::cout, "Hello World!"), string("\n"));
    return 0;
}

实时示例。

有些人确实说标准库中的流库设计不是最漂亮的。


让我惊讶的是第一次调用起作用了。这是在哪里定义的?在std::namespace中作为全局运算符吗?更好的是:operator<<(std::cout, "hello, world").operator<<(std::endl) 这样ADL就能找到 std::operator,对吧? - WorldSEnder
@5gon12eder 是的,我在编辑中包含了可工作的示例。 - luk32
谢谢您的解释。我还有一个问题,ostream中的operator <<std::operator<<有什么区别?在我提出的问题中,我们使用的是std::operator <<,但在您的解释中使用的是ostream::operator << - Allanqunzi
@WorldSEnder 我不确定你在问什么。但我编辑了答案并提供了链接。operator<<(std::basic_ostream) 定义在 ostream 中,ADL 在链接的问题和答案中有很好的描述。 - luk32
@Allanqunzi 这些运算符在不同的地方定义。你可以将几乎每个运算符定义为成员函数和非成员函数,但这比仅仅定义 operator<< 更通用。你可以在这里阅读更多信息:http://en.cppreference.com/w/cpp/language/operators 和 https://dev59.com/62855IYBdhLWcg3wUCWC#4421729。 - luk32
显示剩余3条评论

1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接