Jump to content

тип объявления

Это хорошая статья. Нажмите здесь для получения дополнительной информации.

На ++ языке программирования C decltype ключевое слово, для запроса типа выражения используемое . Представленный в C++11 , он в основном предназначен для использования в универсальном программировании , где часто сложно или даже невозможно выражать типы, зависящие от параметров шаблона .

Поскольку в 1990-е годы общие методы программирования становились все более популярными, была признана необходимость в механизме вывода типов. Многие поставщики компиляторов реализовали свои собственные версии оператора, обычно называемые typeofи были разработаны некоторые переносимые реализации с ограниченной функциональностью, основанные на существующих функциях языка. В 2002 году Бьярн Страуструп предложил добавить стандартизированную версию оператора в язык C++ и предложил название «decltype», чтобы отразить, что оператор будет возвращать «объявленный тип» выражения.

decltypeСемантика была разработана, чтобы удовлетворить потребности как авторов общих библиотек, так и начинающих программистов. В общем, выведенный тип соответствует типу объекта или функции точно так, как объявлено в исходном коде. Как sizeof[1] оператор, decltypeоперанд не оценивается.

Мотивация

[ редактировать ]

С появлением шаблонов в языке программирования C++ и появлением программирования общих методов , впервые предложенных Стандартной библиотекой шаблонов , возникла необходимость в механизме получения типа выражения , обычно называемого typeof, был признан. В обобщенном программировании часто бывает сложно или невозможно выразить типы, зависящие от параметров шаблона. [2] [3] в частности, тип возвращаемого экземпляра шаблона функции. [2]

Многие поставщики предоставляют typeof оператор как расширение компилятора. [4] Еще в 1997 году, до полной стандартизации C++, Брайан Паркер предложил переносимое решение, основанное на sizeof оператор. [4] Его работу расширил Билл Гиббонс, который пришел к выводу, что эта техника имеет несколько ограничений и, как правило, менее эффективна, чем настоящая техника. typeof механизм. [4] В статье в журнале Dr. Dobb's Journal за октябрь 2000 года Александреску Андрей заметил , что «наличие typeof облегчит написание и понимание кода шаблонов». [5] Он также отметил, что «typeof и sizeof используют один и тот же сервер, потому что sizeof в любом случае должен вычислять тип». [5] Эндрю Кениг и Барбара Э. Му также признали полезность встроенного typeof с оговоркой, что «его использование часто приводит к тонким ошибкам программирования, и есть некоторые проблемы, которые оно не может решить». [6] Они охарактеризовали использование соглашений типов, таких как определения типов, предоставляемые стандартной библиотекой шаблонов , как более мощный и общий метод. [6] Однако Стив Дьюхерст утверждал, что такие соглашения «дорогостоящие в разработке и распространении», и что было бы «гораздо проще… просто извлечь тип выражения». [7] В статье о C++0x 2011 года Кениг и Му предсказали, что «decltype будет широко использоваться для облегчения написания повседневных программ». [8]

В 2002 году Бьерн Страуструп предложил расширить язык C++ механизмами запроса типа выражения и инициализации объектов без указания типа. [2] Страуструп заметил, что семантика удаления ссылок, предлагаемая typeof оператор, предоставляемый компиляторами GCC и EDG , может быть проблематичным. [2] И наоборот, оператор, возвращающий ссылочный тип на основе lvalue выражения, считался слишком запутанным. Первоначальное предложение комитету по стандартам C++ предусматривало комбинацию двух вариантов; оператор вернет ссылочный тип только в том случае, если объявленный тип выражения включает ссылку. Чтобы подчеркнуть, что выведенный тип будет отражать «объявленный тип» выражения, оператору было предложено дать имя decltype. [2]

Одна из основных причин, побудивших decltype Предложением была возможность писать идеальные шаблоны функций пересылки . [9] Иногда желательно написать универсальную функцию пересылки, которая возвращает тот же тип, что и обернутая функция, независимо от типа, с которым она создана. Без decltype, обычно это невозможно сделать. [9] Пример, в котором также используется тип Trailing-Return : [9]

int& foo(int& i);
float foo(float& f);

template <class T> auto transparent_forwarder(T& t) > decltype(foo(t)) {
  return foo(t);
}

decltype здесь важен, поскольку он сохраняет информацию о том, возвращает ли обернутая функция ссылочный тип. [10]

Семантика

[ редактировать ]

Аналогично sizeof оператор, операнд decltype не оценивается, поэтому такие выражения, как decltype(i++) не приведет к увеличению переменной i. [11] Неформально, тип, возвращаемый decltype(e) выводится следующим образом: [2]

  1. Если выражение e относится к переменной в локальной области или области имен, статической переменной-члену или параметру функции, тогда результатом является объявленный тип этой переменной или параметра.
  2. В противном случае, если e это lvalue , decltype(e) является T&, где T — тип e; если e является значением x , результат T&&; в противном случае e является prvalue и результатом будет T.
  3. В качестве частного случая decltype(auto) позволяет выводить тип, например auto но он сохраняет категорию значений инициализатора. Более конкретно, это эквивалентно decltype(initializer).

Эта семантика была разработана для удовлетворения потребностей разработчиков универсальных библиотек и в то же время была интуитивно понятной для начинающих программистов, поскольку тип возвращаемого значения decltype всегда соответствует типу объекта или функции точно так, как указано в исходном коде. [2] Более формально, Правило 1 применяется к выражениям id без скобок и выражениям доступа к членам класса. [12] [13] Пример: [12] Обратите внимание на добавленные строки для bar(). Ниже типа, выведенного для "bar()", указан простой int, а не const int, поскольку значения prvalue неклассовых типов всегда имеют неквалифицированные типы cv, несмотря на статически объявленный другой тип.

const int&& foo();
const int bar();
int i;
struct A { double x; };
const A* a = new A();
decltype(foo()) x1; // type is const int&&
decltype(bar()) x2; // type is int
decltype(i) x3; // type is int
decltype(a->x) x4; // type is double
decltype((a->x)) x5; // type is const double&

Причина различия между двумя последними вызовами decltype заключается в том, что выражение в скобках (a->x) не является ни выражением идентификатора , ни выражением доступа к члену и, следовательно, не обозначает именованный объект. [14] Поскольку выражение является lvalue, его выведенным типом является «ссылка на тип выражения», или const double&. [11] Тот факт, что дополнительные круглые скобки вводят к типу ссылочный квалификатор, может стать источником ошибок для программистов, которые не до конца понимают decltype. [15]

В декабре 2008 года Яакко Ярви выразил обеспокоенность комитету по поводу невозможности использования decltype для формирования квалифицированного идентификатора , [1] что противоречит намерению decltype(e) следует рассматривать «как если бы это было имя typedef ». [16] Комментируя официальный проект комитета по C++0x , японский орган-член ISO отметил, что «оператор области видимости (::) не может быть применен к decltype, но это следует сделать. Было бы полезно в случае получения типа члена (вложенный тип) из экземпляра следующим образом: [17]

vector<int> v;
decltype(v)::value_type i = 0; // int i = 0;

Этот и подобные вопросы, касающиеся формулировки, запрещающей использование decltype в объявлении производного класса и в вызове деструктора были рассмотрены Дэвидом Вандевурдом и проголосованы за рабочий документ в марте 2010 года. [18] [19]

Доступность

[ редактировать ]

decltype включен в стандарт языка C++, начиная с C++11 . [12] Он предоставляется рядом компиляторов в качестве расширения. Microsoft Компиляторы Visual C++ 2010 и более поздних версий предоставляют decltype спецификатор типа, который точно имитирует семантику, описанную в предложении комитета по стандартам. Его можно использовать как с управляемым, так и с собственным кодом. [10] В документации указано, что это «полезно в первую очередь разработчикам, которые пишут библиотеки шаблонов». [10] decltype был добавлен в основную строку компилятора GCC C++ в версии 4.3, [20] выпущен 5 марта 2008 г. [21] decltype также присутствует в Codegear от C++ Builder 2009 , [22] компилятор Intel C++ , [23] и Кланг . [24]

  1. ^ Перейти обратно: а б Миллер, Уильям М. (29 сентября 2009 г.). «Активные проблемы стандартного базового языка C++, редакция 66» . ISO/IEC JTC1/SC22/WG21 — Комитет по стандартам C++ . Проверено 3 октября 2009 г.
  2. ^ Перейти обратно: а б с д и ж г Грегор, Дуглас; Ярви, Джеймс; Сик, Джереми; Страуструп, Бьярне (28 апреля 2003 г.). «Decltype и авто» (PDF) . ISO/IEC JTC1/SC22/WG21 — Комитет по стандартам C++ . Проверено 28 августа 2015 г.
  3. ^ Калев, Дэнни (8 мая 2008 г.). «Очистка синтаксиса функции с помощью decltype » . DevX.com . Проверено 4 сентября 2009 г.
  4. ^ Перейти обратно: а б с Гиббонс, Билл (1 ноября 2000 г.). «Портативный оператор типа «Оператор» . Журнал доктора Добба . Проверено 3 сентября 2009 г.
  5. ^ Перейти обратно: а б Александреску, Андрей (01 октября 2000 г.). «Generic<Programming>: Сопоставления между типами и значениями» . Журнал доктора Добба . Проверено 3 сентября 2009 г.
  6. ^ Перейти обратно: а б Кениг, Эндрю; Барбара Э. Му (1 февраля 2002 г.). «С++ стал проще: именование неизвестных типов» . Журнал доктора Добба . Проверено 3 сентября 2009 г.
  7. ^ Дьюхерст, Стив (1 августа 2000 г.). «Общие знания: оператор побитового типа, часть 1» . Журнал доктора Добба . Проверено 3 сентября 2009 г.
  8. ^ Кениг, Эндрю; Барбара Э. Му (19 июля 2011 г.). «4 полезных новых функции в C++0x» . Доктор Журнал Добба . Проверено 12 января 2012 г.
  9. ^ Перейти обратно: а б с Дос Рейс, Габриэль; Ярви, Джеймс; Страуструп, Бьярне (12 октября 2004 г.). «Decltype и auto (редакция 4)» (PDF) . ISO/IEC JTC1/SC22/WG21 — Комитет по стандартам C++ . Проверено 4 сентября 2009 г.
  10. ^ Перейти обратно: а б с «Оператор decltype» . Корпорация Майкрософт . Проверено 4 сентября 2009 г.
  11. ^ Перейти обратно: а б Дос Рейс, Габриэль; Ярви, Джеймс; Страуструп, Бьярне (18 июля 2007 г.). «Decltype (редакция 7): предлагаемая формулировка» (PDF) . ISO/IEC JTC1/SC22/WG21 — Комитет по стандартам C++ . Проверено 4 сентября 2009 г.
  12. ^ Перейти обратно: а б с Беккер, Пит. «Рабочий проект стандарта языка программирования C++» (PDF) . ISO/IEC JTC1/SC22/WG21 — Комитет по стандартам C++ . Проверено 4 сентября 2009 г.
  13. ^ Миллер, Уильям М. (3 августа 2009 г.). «Отчеты о дефектах стандартного базового языка C++, редакция 65» . ISO/IEC JTC1/SC22/WG21 — Комитет по стандартам C++ . Проверено 15 сентября 2009 г.
  14. ^ Миллер, Уильям М. (3 августа 2009 г.). «Закрытые проблемы стандартного базового языка C++, редакция 65» . ISO/IEC JTC1/SC22/WG21 — Комитет по стандартам C++ . Проверено 4 сентября 2009 г.
  15. ^ Мазьер, Давид (июнь 2021 г.). «Категории значений C++ и decltype раскрыты» . Проверено 16 июня 2022 г.
  16. ^ Дос Рейс, Габриэль; Ярви, Джеймс; Страуструп, Бьярне (5 ноября 2006 г.). «Decltype (редакция 6): предлагаемая формулировка» (PDF) . ISO/IEC JTC1/SC22/WG21 — Комитет по стандартам C++ . Проверено 3 октября 2009 г.
  17. ^ Миллер, Уильям М. (3 августа 2009 г.). «Состояние комментариев C++ CD1» . ISO/IEC JTC1/SC22/WG21 — Комитет по стандартам C++ . Проверено 3 октября 2009 г.
  18. ^ Миллер, Уильям М. (29 марта 2010 г.). «Отчеты о дефектах стандартного базового языка C++, редакция 69» . ISO/IEC JTC1/SC22/WG21 — Комитет по стандартам C++ . Проверено 10 апреля 2010 г.
  19. ^ Вандевурде, Дэвид (3 февраля 2010 г.). «Основные проблемы 743 и 950: дополнительное использование decltype(...)» (PDF) . ISO/IEC JTC1/SC22/WG21 — Комитет по стандартам C++ . Проверено 10 апреля 2010 г.
  20. ^ «Поддержка C++0x в GCC» . Фонд свободного программного обеспечения . 27 августа 2009 г. Проверено 4 сентября 2009 г.
  21. ^ «Серия выпусков GCC 4.3» . Фонд свободного программного обеспечения . 13 августа 2009 г. Проверено 4 сентября 2009 г.
  22. ^ «Спецификатор типа decltype (C++0x)» . Эмбаркадеро Технологии. Архивировано из оригинала 8 июля 2011 г. Проверено 4 сентября 2009 г.
  23. ^ "стандартный, Qstd" . Корпорация Интел . Проверено 4 сентября 2009 г.
  24. ^ Грегор, Дуглас (26 января 2011 г.). «Поддержка новых функций C++0x в Clang» . Архивировано из оригинала 30 января 2011 г.
[ редактировать ]

Arc.Ask3.Ru: конец переведенного документа.
Arc.Ask3.Ru
Номер скриншота №: 674b3c0fd44fd627aaac17e8f6ce5516__1701628260
URL1:https://arc.ask3.ru/arc/aa/67/16/674b3c0fd44fd627aaac17e8f6ce5516.html
Заголовок, (Title) документа по адресу, URL1:
decltype - Wikipedia
Данный printscreen веб страницы (снимок веб страницы, скриншот веб страницы), визуально-программная копия документа расположенного по адресу URL1 и сохраненная в файл, имеет: квалифицированную, усовершенствованную (подтверждены: метки времени, валидность сертификата), открепленную ЭЦП (приложена к данному файлу), что может быть использовано для подтверждения содержания и факта существования документа в этот момент времени. Права на данный скриншот принадлежат администрации Ask3.ru, использование в качестве доказательства только с письменного разрешения правообладателя скриншота. Администрация Ask3.ru не несет ответственности за информацию размещенную на данном скриншоте. Права на прочие зарегистрированные элементы любого права, изображенные на снимках принадлежат их владельцам. Качество перевода предоставляется как есть. Любые претензии, иски не могут быть предъявлены. Если вы не согласны с любым пунктом перечисленным выше, вы не можете использовать данный сайт и информация размещенную на нем (сайте/странице), немедленно покиньте данный сайт. В случае нарушения любого пункта перечисленного выше, штраф 55! (Пятьдесят пять факториал, Денежную единицу (имеющую самостоятельную стоимость) можете выбрать самостоятельно, выплаичвается товарами в течение 7 дней с момента нарушения.)