Подтвердить что ты не робот

Разница между decltype и typeof?

Два вопроса относительно decltype и typeof:

  • Есть ли разница между операторами decltype и typeof?
  • Устраняется ли typeof в С++ 11?
4b9b3361

Ответ 1

В c++ нет оператора typeof. Хотя верно, что такая функциональность была предложена большинством компиляторов в течение некоторого времени, она всегда была специфическим языковым расширением для компилятора. Поэтому сравнение поведения двух в целом не имеет смысла, поскольку поведение typeof (если оно даже существует) чрезвычайно зависит от платформы.

Поскольку теперь у нас есть стандартный способ получения типа переменной/выражения, на самом деле нет оснований полагаться на не переносимые расширения, поэтому я бы сказал, что он довольно устарел.

Еще одна вещь, которую следует учитывать, заключается в том, что если поведение typeof несовместимо с decltype для данного компилятора, возможно, расширение typeof не получит большого развития, чтобы охватить новые языковые функции в будущее (это означает, что это может просто не работать, например, lambdas). Я не знаю, действительно ли это так, но это отличная возможность.

Ответ 2

Разница между ними заключается в том, что 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 использовался для вывода переменных.

Ответ 3

Для устаревшего кода я успешно использовал следующее:

#include <type_traits>
#define typeof(x) std::remove_reference<decltype((x))>::type

Ответ 4

typeof не был стандартизирован, хотя он был реализован несколькими поставщиками компиляторов, например GCC. Это стало устаревшим с decltype.

Хорошее объяснение недостатков типаof можно найти в этом связанном ответе.

Ответ 5

Ну, typeof - это нестандартное расширение GNU C, которое вы можете использовать в GNU С++, потому что GCC позволяет использовать функции других языков в другом (не всегда), поэтому их действительно не следует сравнивать.

Конечно, другие нестандартные расширения могут существовать для других компиляторов, но GCC определенно является наиболее широко документированной реализацией.

Чтобы ответить на вопрос: он не может быть устаревшим, если он никогда не был функцией.

Если вы хотите сравнить достоинства любого из методов в С++, тогда семантически нет разницы, если вы не имеете дело со ссылками. Вы должны использовать decltype, потому что он портативен и соответствует стандартам.