Является ли оператор void*() преобразованием по-прежнему частью библиотеки C++?
Рассмотрим эту программу:
#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), но она выдает предупреждение, а не ошибку компилятора. Идеальный компилятор выдает ошибку, как и ожидалось. (Смотрите демо-версию здесь)
2 ответа
Это не имеет ничего общего с компилятором, это проблема библиотеки. libstdC++ имеет много несовместимостей с C++11, и это только одна из них. Они делают серьезные изменения в 5 и выше, хотя IIRC.
Короче говоря, это не ошибка и не проблема компилятора.
Это ошибка в стандартной библиотеке (если вы рассматриваете ее как реализацию стандартной библиотеки C++11/14, а не C++98/03).
Хотя это и проблема компилятора. В частности, удаление преобразования в void *
зависит от добавления конверсии непосредственно в bool
- но это, в свою очередь, зависит от добавления "контекстного преобразования" к компилятору.
В gcc 4.8 реализована форма контекстного преобразования, но не форма, принятая в стандарте. Хотя конкретные изменения в контекстном преобразовании не будут напрямую влиять на это использование контекстного преобразования, это все же указывает на тот факт, что определение контекстного преобразования все еще изменялось, когда создавались эти компиляторы.
Последовательность, в которой происходят события (по крайней мере, обычно), заключается в том, что сначала спецификация затвердевает. Затем компилятор реализует это. Затем стандартная библиотека использует его.
В этом случае спецификация все еще изменялась незадолго до выпуска компилятора. Поэтому стандартная библиотека не использовала (и практически не могла) ее использовать.
Ко времени выпуска 4.9 спецификация была твердой, и компилятор реализовал окончательную версию контекстного преобразования, но она еще не была достаточно долгой, чтобы ее можно было использовать в стандартной библиотеке.