为什么流输出中的 < 而不是 << 仍然可以编译?

Why does < instead of << in stream output still compile?

今天我在我的程序中犯了一个小错别字,虽然程序编译正常,但我一直在想为什么我没有得到任何输出。基本上它减少到这个:

#include <iostream>

int main()
{
    std::cout < "test"; // no << but <
}

我完全不知道这里执行了什么样的隐式转换,所以程序仍然可以编译(g++4.9.2 甚至 g++5)。我刚刚意识到 clang++ 拒绝了代码。是否正在执行 void* 的转换(想不出其他任何东西)?我记得看到过类似的东西,但我认为它在 g++5 中得到了解决,但似乎并非如此。

编辑: 我没有使用 -std=c++11 进行编译,因此代码在 C++11 之前的版本中有效(由于转换为 void* ostream)。当用 -std=c++11 编译时,g++5 拒绝代码,g++4.9 仍然接受它。

这仅在 C++11 之前有效。

你基本上是在做:((void *) std::cout) < ((char *) "test")

是的,编译器正在将 cout 转换为 void*。如果您使用 -S 开关来反汇编代码,您将看到类似这样的内容:

    mov edi, OFFSET FLAT:std::cout+8
    call    std::basic_ios<char, std::char_traits<char> >::operator void*() const
    cmp rax, OFFSET FLAT:.LC0
    setb    al
    test    al, al

这清楚地表明 operator void* 是罪魁祸首。

与 Bill Lynch 所说的相反,我可以在 Compiler Explorer 上用 —std=c++11 重现它。然而,它似乎是一个实现缺陷,因为 C++11 应该在 basic_ios.

上用 operator bool 替换 operator void*