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

vso*_*tco 11 c++ ostream implicit-conversion

今天我在我的程序中输了一个小错误,并且为什么我没有得到任何输出而徘徊,尽管程序编译得很好.基本上它减少到这个:

#include <iostream>

int main()
{
    std::cout < "test"; // no << but <
}
Run Code Online (Sandbox Code Playgroud)

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

编辑:我不与编译-std=c++11,所以代码是有效的在预C++ 11(由于转换到void*ostream).当用-std=c++11g ++ 5 编译时拒绝代码,g ++ 4.9仍然接受它.

zne*_*eak 9

是的,编译器正在转换coutvoid*.如果您使用-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
Run Code Online (Sandbox Code Playgroud)

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

与Bill Lynch所说的相反,我可以—std=c++11Compiler Explorer上重现它.但是,它似乎确实是一个实现缺陷,因为C++ 11应该替换operator void*operator boolon basic_ios.


Bil*_*nch 5

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

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