Прямая передача (C++)

Прямая передача (англ. Perfect Forwarding) — идиоматический механизм переноса атрибутов параметров в процедурах обобщённого кода языка C++. Он был стандартизирован в редакции стандарта C++11 с помощью функционала библиотеки STL и синтаксиса передаваемыx ссылок (англ. forwarding references), а также унифицирован для применения совместно с вариативными шаблонами[1][2].

Прямая передача используется в тех случаях, когда от функций и процедур обобщённого кода требуется оставлять неизменными фундаментальные свойства своих параметризованных аргументов, то есть[1]:

  • константный объект должен передаваться как объект, предназначенный только для чтения.
  • модифицируемый объект должен оставаться модифицируемым.
  • перемещаемый объект должен оставаться перемещаемым.

Это достигается тем, что поведение &&-аргументов шаблонов отличается от традиционных &&-ссылок, хотя и подчиняется тем же самым правилам. Несмотря на идентичный синтаксис их семантика для компилятора имеет существенные отличия[3]:

  • &&-ссылка для конкретного типа интерпретируется как rvalue-ссылка, которая может быть связана только с перемещаемыми объектами.
  • &&-ссылка для параметра шаблона интерпретируется как передаваемая или универсальная ссылка, которая может быть связана с изменяемым, константным или перемещаемым объектом.

Механизм вывода аргументов шаблонa подчиняется стандартному правилу свёртки (коллапсирования) ссылок (англ. reference collapsing). При переходе к передаваемым ссылкам выясняется не только тип переданного в функцию параметра, но также даётся оценка, является ли он rvalue или lvalue. Если переданный в функцию параметр является lvalue, то подставляемое значение тоже будет ссылкой на lvalue. При этом, отмечается, что объявление типа параметра шаблона в виде &&-ссылки может иметь интересные побочные эффекты. Например, проявляется необходимость явного указания инициализаторов для всех локальных переменных данного типа, так как при их использовании с lvalue-параметрами вывод типа после инстанцирования шаблона присвоит им значение lvalue-ссылки, которая по требованию языка обязана иметь инициализатор[4].

Практическое воплощение прямой передачи в стандарте языка реализовано с помощью функции std::forward из заголовочного файла <utility>[5][6]. Вследствие чего, комбинация специальных правил вывода для &&-ссылок и их свёртки позволяет создать функциональный шаблон, который принимает произвольные аргументы с фиксацией их типов и основных свойств (rvalue или lvalue). Сохранение этой информации предопределяет возможность передавать данные аргументы при вызове других функций и методов[7].

Примечания

  1. Вандевурд, 2018, 6.1 Прямая передача, с. 125.
  2. Horton, 2014, Perfect Forwarding, p. 373.
  3. Вандевурд, 2018, 6.1 Прямая передача, с. 127.
  4. Вандевурд, 2018, 15.6.2 Передаваемые ссылки, с. 331.
  5. std::forward C++ reference
  6. Вандевурд, 2018, 15.6.3 Прямая передача, с. 333.
  7. Вандевурд, 2018, 15.6.3 Прямая передача, с. 332.

Источники

  • Д. Вандевурд, Н. Джосаттис, Д. Грегор. Шаблоны C++. Справочник разработчика = C++ Templates. The Complete Guide. — 2-е. СПб. : «Альфа-книга», 2018. — 848 с. — ISBN 978-5-9500296-8-4.
  • I. Horton. Ivor Horton’s Beginning Visual C++ ® 2013. — John Wiley & Sons, Inc., 2014. — ISBN 978-1-118-84577-6.

Ссылки

This article is issued from Wikipedia. The text is licensed under Creative Commons - Attribution - Sharealike. Additional terms may apply for the media files.