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

时间:2015-04-18 22:06:49

标签: c++ implicit-conversion ostream

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

#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仍然接受它。

2 个答案:

答案 0 :(得分:9)

是的,编译器正在将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应该在operator void*上用operator bool替换basic_ios

答案 1 :(得分:5)

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

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