Почему <вместо << в потоке вывод еще компилируется?

Сегодня я сделал небольшую опечатку в своей программе и блуждал, почему я не получал никакого результата, хотя программа скомпилирована. В основном это сводится к следующему:

#include <iostream>

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

Я абсолютно не знаю, какое именно неявное преобразование выполняется здесь, поэтому программа все еще компилируется (как g++ 4.9.2, так и даже g++ 5). Я просто понял, что clang++ отклоняет код. Происходит ли преобразование в void* (не может думать ни о чем другом)? Я помню, что видел что-то подобное, но я думал, что это было рассмотрено в g++ 5, но это, похоже, не так.

EDIT: Я не компилировал с -std=c++11, поэтому код был действителен в pre-С++ 11 (из-за преобразования в void* из ostream). Когда компиляция с -std=c++11 g++ 5 отклоняет код, g++ 4.9 все еще принимает его.

Ответ 1

Да, компилятор преобразует 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* является виновником.

Вопреки тому, что сказал Билл Линч, я могу воспроизвести его с помощью —std=c++11 в > Compiler Explorer. Однако он, по-видимому, является дефектом реализации, поскольку С++ 11 должен был заменить operator void* на operator bool на basic_ios.

Ответ 2

Это допустимо только до С++ 11.

В основном вы делаете: ((void *) std::cout) < ((char *) "test")