Два вопроса относительно decltype
и typeof
:
- Есть ли разница между операторами
decltype
иtypeof
? - Устраняется ли
typeof
в С++ 11?
Два вопроса относительно decltype
и typeof
:
decltype
и typeof
?typeof
в С++ 11?В c++
нет оператора typeof
. Хотя верно, что такая функциональность была предложена большинством компиляторов в течение некоторого времени, она всегда была специфическим языковым расширением для компилятора. Поэтому сравнение поведения двух в целом не имеет смысла, поскольку поведение typeof
(если оно даже существует) чрезвычайно зависит от платформы.
Поскольку теперь у нас есть стандартный способ получения типа переменной/выражения, на самом деле нет оснований полагаться на не переносимые расширения, поэтому я бы сказал, что он довольно устарел.
Еще одна вещь, которую следует учитывать, заключается в том, что если поведение typeof
несовместимо с decltype
для данного компилятора, возможно, расширение typeof
не получит большого развития, чтобы охватить новые языковые функции в будущее (это означает, что это может просто не работать, например, lambdas). Я не знаю, действительно ли это так, но это отличная возможность.
Разница между ними заключается в том, что 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."
J. Джарви, Б. Страуструп, Д. Грегор, Й. Зик: Деклатип и авто. N1478/03-0061.
Так что некорректно сказать, что decltype
полностью устранен typeof
(если вы хотите использовать семантику выделения ссылок, то расширение типа в этих компиляторах все еще используется), но, скорее всего, typeof
был в значительной степени устранен им плюс auto
, который отбрасывает ссылки и заменяет использование, где typeof
использовался для вывода переменных.
Для устаревшего кода я успешно использовал следующее:
#include <type_traits>
#define typeof(x) std::remove_reference<decltype((x))>::type
typeof не был стандартизирован, хотя он был реализован несколькими поставщиками компиляторов, например GCC. Это стало устаревшим с decltype.
Хорошее объяснение недостатков типаof можно найти в этом связанном ответе.
Ну, typeof
- это нестандартное расширение GNU C, которое вы можете использовать в GNU С++, потому что GCC позволяет использовать функции других языков в другом (не всегда), поэтому их действительно не следует сравнивать.
Конечно, другие нестандартные расширения могут существовать для других компиляторов, но GCC определенно является наиболее широко документированной реализацией.
Чтобы ответить на вопрос: он не может быть устаревшим, если он никогда не был функцией.
Если вы хотите сравнить достоинства любого из методов в С++, тогда семантически нет разницы, если вы не имеете дело со ссылками. Вы должны использовать decltype
, потому что он портативен и соответствует стандартам.