Прямая передача (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. 1 2 Вандевурд, 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.

Ссылки[править | править код]