Рассмотрим эту программу:
#include <iostream>
int main()
{
delete std::cout;
}
AFAIK функция преобразования оператор void * () const был удален из C ++ 11. Таким образом, эта программа должна потерпеть неудачу при компиляции на компиляторе C ++ 11. Да, это правда, что оба g ++ 4.8.1 & 4.9.2 дает диагноз (в форме предупреждения, что удаление void * не определено & это тоже хорошо). Но не должна ли эта программа потерпеть неудачу при компиляции, потому что удаление этой функции преобразования, из-за которой весь объект потока может быть неявно преобразован в void * в C ++ 98 & C ++ 03 ?. Это ошибка? Кажется немного удивительным, что они все еще не осуществили это изменение.
Я пробовал эту программу в g ++ 4.9.2 (которая поддерживает C ++ 14), но она выдает предупреждение, а не ошибку компилятора. Идеальный компилятор выдает ошибку, как и ожидалось. (Смотрите демо Вот)
Это не имеет ничего общего с компилятором, это проблема библиотеки. libstdc ++ имеет много несовместимостей с C ++ 11, и это только одна из них. Они делают серьезные изменения в 5 и выше, хотя IIRC.
Короче говоря, это не ошибка и не проблема компилятора.
Это ошибка в стандартной библиотеке (если вы рассматриваете ее как реализацию стандартной библиотеки C ++ 11/14, а не C ++ 98/03).
Хотя это и проблема компилятора. В частности, удаление преобразования в void *
зависит от добавления конверсии непосредственно в bool
— но это, в свою очередь, зависит от добавления «контекстного преобразования» к компилятору.
В gcc 4.8 реализована форма контекстного преобразования, но не форма, принятая в стандарте. Хотя конкретные изменения в контекстном преобразовании не будут непосредственно влияя на это использование контекстного преобразования, оно указывает на тот факт, что определение контекстного преобразования все еще корректировалось, когда эти компиляторы были написаны.
Последовательность, в которой происходят события (по крайней мере, обычно), заключается в том, что сначала спецификация затвердевает. Затем компилятор реализует это. Затем стандартная библиотека использует его.
В этом случае спецификация все еще изменялась незадолго до выпуска компилятора. Поэтому стандартная библиотека не использовала (и практически не могла) ее использовать.
Ко времени выпуска 4.9 спецификация была твердой, и компилятор реализовал окончательную версию контекстного преобразования, но она еще не была достаточно долгой, чтобы ее можно было использовать в стандартной библиотеке.