Два вопроса относительно decltype
а также typeof
:
decltype
а также typeof
операторы?typeof
устареть в C ++ 11?Здесь нет typeof
оператор в c++
, Хотя это верно, что такая функциональность была предложена большинством компиляторов в течение достаточно долгого времени, она всегда была расширением для конкретного компилятора. Поэтому сравнивать поведение обоих в целом не имеет смысла, так как поведение typeof
(если он вообще существует) сильно зависит от платформы.
Поскольку теперь у нас есть стандартный способ получения типа переменной / выражения, нет никаких оснований полагаться на непереносимые расширения, поэтому я бы сказал, это в значительной степени устарело.
Еще одна вещь, которую следует учитывать, это то, что если поведение typeof
не совместим с decltype
для данного компилятора возможно, что typeof
Расширение не получит большого развития, чтобы охватить новые языковые функции в будущем (то есть оно может просто не работать, например, с лямбдами). Я не знаю, так ли это в настоящее время, но это вполне возможно.
Разница между ними заключается в том, что decltype
всегда сохраняет ссылки как часть информации, тогда как typeof
может нет. Так…
int a = 1;
int& ra = a;
typeof(a) b = 1; // int
typeof(ra) b2 = 1; // int
decltype(a) b3; // int
decltype(ra) b4 = a; // reference to int
Имя typeof
был предпочтительным выбором (в соответствии с sizeof
а также alignof
и имя, уже используемое в расширениях), но, как вы можете видеть в предложении N1478, из-за проблем совместимости с существующими реализациями удаление ссылок привело к тому, что они дали ему другое имя.
«Мы используем имя оператора typeof при обращении к механизму запроса типа выражения в целом. Оператор decltype относится к предлагаемому варианту typeof. … Некоторые поставщики компиляторов (EDG, Metrowerks, GCC) предоставляют оператор typeof как расширение с семантикой отбрасывания ссылок. Как описано в Разделе 4, это кажется идеальным для выражения типа переменных. С другой стороны, семантика отбрасывания ссылок не обеспечивает механизм для точного выражения возвращаемых типов универсальных функции … В этом предложении семантика оператора, предоставляющего информацию о типе выражений, отражает объявленный тип. Поэтому мы предлагаем использовать имя оператора decltype. «
Дж. Ярви, Б. Страуструп, Д. Грегор, Дж. Зик: Decltype и auto. N1478 / 03-0061.
Поэтому неправильно говорить, что decltype
полностью устранен typeof
(если вы хотите семантику удаления ссылок, то расширение typeof в этих компиляторах все еще используется), а, скорее, typeof
было в значительной степени устранено этим плюс auto
, который сбрасывает ссылки и заменяет использование где typeof
был использован для вывода переменных.
Для старого кода я успешно использовал следующее:
#include <type_traits>
#define typeof(x) std::remove_reference<decltype((x))>::type
typeof не был стандартизирован, хотя он был реализован несколькими поставщиками компиляторов, например, НКУ. Это стало устаревшим с decltype.
Хорошее объяснение недостатков typeof можно найти в этом связанном ответе.
Что ж, typeof
это нестандартное расширение GNU C, которое вы можете использовать в GNU C ++, потому что GCC позволяет вам использовать функции из других языков в другом (хотя и не всегда), поэтому их не следует сравнивать.
Конечно, другие нестандартные расширения могут существовать для других компиляторов, но GCC, безусловно, является наиболее широко документированной реализацией.
Чтобы ответить на вопрос: он не может быть устаревшим, если он никогда не был функцией.
Если вы хотите сравнить достоинства любого из методов в C ++, то семантически нет никакой разницы, если вы не имеете дело со ссылками. Вы должны использовать decltype
потому что это портативно и соответствует стандартам.