Студопедия

Главная страница Случайная страница

Разделы сайта

АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника






Суффиксный синтаксис возвращаемого значения






Давайте рассмотрим пример:

template< class T, class U>??? mul(T x, U y) { return x*y; }

 

Что мы должны записать в качестве типа возвращаемого значения? Конечно же, это тип выражения x*y, но как нам его указать. Первая мысль, с помощью decltype:

template< class T, class U> decltype(x*y) mul(T x, U y) // Проблема с видимостью! { return x*y; }

 

Этот вариант не работает, поскольку x и y используются за пределами их области видимости. Однако мы можем записать так:

// Ужасно! И чревато ошибками template< class T, class U> decltype(*(T*)(0)**(U*)(0)) mul(T x, U y) { return x*y; }

 

И сказать, что этот вариант «не очень» - это ничего не сказать.

Решение же заключается в помещении типа возвращаемого значения на его место – после аргументов:

template< class T, class U> auto mul(T x, U y) -> decltype(x*y) { return x*y; }

 

Мы используем ключевое слово auto, которое говорит, что «тип возвращаемого значения будет выведен или указан позднее».

На самом деле суффиксный синтаксис связан не столько с шаблонами и выводом типов, сколько с областью видимости.

struct List { struct Link { /*... */ }; // Удаляем p, возвращаем указатель на узел, предыдущий p Link* erase(Link* p); //... }; List:: Link* List:: erase(Link* p) { /*... */ }

 

Первый префикс List:: необходим только потому, что область типа List еще не начинается до второго List::. Вот более простой вариант:

auto List:: erase(Link* p) -> Link* { /*... */ }

 

Теперь ни одно из упоминаний Link не требует явной квалификации имен.

См. также:

  • the C++ draft section???
  • [Str02] Bjarne Stroustrup. Draft proposal for " typeof". C++ reflector message c++std-ext-5364, October 2002.
  • [N1478=03-0061] Jaakko Jarvi, Bjarne Stroustrup, Douglas Gregor, and Jeremy Siek: Decltype and auto.
  • [N2445=07-0315] Jason Merrill: New Function Declarator Syntax Wording.
  • [N2825=09-0015] Lawrence Crowl and Alisdair Meredith: Unified Function Syntax.

 

template alias (известные ранее как “template typedef”)

Как нам создать шаблон, «аналогичный другому шаблону», но, возможно, с несколькими указанными (привязанными, bound) шаблонными аргументами? Давайте рассмотрим пример:

template< class T> // Стандартный вектор, использующий мой аллокатор using Vec = std:: vector< T, My_alloc< T> >; // Элементы выделяются с помощьюMy_alloc Vec< int> fib = { 1, 2, 3, 5, 8, 13 }; // verbose и fib одного типа vector< int, My_alloc< int> > verbose = fib;

 

Ключевое слово using используется для получения линейной нотации: «имя, за которым следует то, на что оно ссылается». Мы попробовали использовать стандартное и довольно запутанное решение на основе typedef, но так и не смогли добиться полного и ясного решения, пока не пришли к менее запутанному синтаксису.

Специализация работает (вы можете создать синоним (alias) для набора специализаций, но не можете специализировать псевдонимы). Например:

template< int> // Идея: int_exact_trait< N>:: type тип в точности из N бит struct int_exact_traits { typedef int type; }; template< > struct int_exact_traits< 8> { typedef char type; }; template< > struct int_exact_traits< 16> { typedef char[2] type; }; //... // Создаем синоним для более удобного использования template< int N> using int_exact = typename int_exact_traits< N>:: type; // int_exact< 8> является целочисленной переменной из 8 бит int_exact< 8> a = 7;

 

Помимо использования синонимов типов совместно с шаблонами, они могут использоваться в качестве альтернативного (и, ИМО более удачного) синтаксиса для синонимов обычных типов:

typedef void (*PFD)(double); // C style using PF = void (*)(double); // using plus C-style type using P = [](double)-> void; // using plus suffix return type

 

См. также:

  • the C++ draft: 14.6.7 Template aliases; 7.1.3 The typedef specifier
  • [N1489=03-0072] Bjarne Stroustrup and Gabriel Dos Reis: Templates aliases for C++.
  • [N2258=07-0118] Gabriel Dos Reis and Bjarne Stroustrup: Templates Aliases (Revision 3) (final proposal).

 






© 2023 :: MyLektsii.ru :: Мои Лекции
Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав.
Копирование текстов разрешено только с указанием индексируемой ссылки на источник.