Добавил:
t.me Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

2 семестр / Литература / Язык программирования С++. Краткий курс. Страуструп

.pdf
Скачиваний:
9
Добавлен:
16.07.2023
Размер:
31.34 Mб
Скачать

13.S.

Альтернативы

245

auto auto auto

s х d

get<string>(tl); get<int>(tl); get<douЫe>(tl);

11 11 11

Получение Получение Получение

string:

"Shark"

int: 123

 

douЫe:

3.14

Можно

использовать

get<>

и

для

записи:

get<string>(tl)

=

get<int>(tl) =

7;

get<douЫe>(tl)

=

"Типа"; 312;

11 // //

Запись Запись Запись

в в в

string int douЫe

Как

и

пары, кортежи

можно

присваивать

и

сравнивать, если

их

элементы

могут

это

делать.

Как

и

к

элементам

tuple,

к

элементам

pair

можно

полу­

чить

доступ,

используя

get<>

().

Структурное связывание (§3.6.3)

применимо к tuple так же, как и

к pair.

Однако, когда коду не требуется обобщенность, простая структура с

имено­

ванными членами часто приводит к

более понятному и легче поддерживаемо­

му

коду.

13.5.

Альтернативы

Стандартная

библиотека

предлагает

три

типа

для

выражения

альтернатив:

var ian t -

для представления одной из определенного множества аль­

тернатив (заголовочный файл-

<variant>);

 

 

optional -

для представления

значения определенного типа

или

от­

сутствия значения (заголовочный файл- <optional>);

 

 

any -

для представления одного

из неограниченного

тернативных типов (заголовочный

файл -

<any>).

множества

аль­

Эти три типа предлагают пользователю схожие функциональные ности. К сожалению, они не предлагают единого интерфейса.

возмож­

13.5.1.

variant

variant<A,

В,

С>

зачастую

является

более

удобной

и

безопасной

альтер­

нативой

явному

использованию

union

(§2.4).

Возможно,

простейшим

приме­

ром

применения

является

возврат

либо

значения,

либо

кода

ошибки:

variant<string,int> {

compose_message(istream&

s)

string

mess;

11

...

Чтение из

if

(no_proЬlems)

 

return

mess;

else

 

 

 

return

error

s и составление сообщения ...

 

//

Возврат

string

numЬer;

//

Возврат

int

248

Глава

13.

Утилиты

Это нравится

некоторым программистам,

ключения (см. §

3.5.5). Обратите внимание на

которые недолюбливают ис­ любопытное использование *.

optional

рассматривается

как

указатель

на

свой

объект,

а

не

как

сам

объект.

optional,

являющийся

эквивалентом

nullptr,

-

пустой

объект

{ }.

На­

пример:

int

cat(optional<int>

а,

optional<int>

Ь)

int

res

if

(а)

if

(Ь)

return

=

О;

res

+=

res

+=

res;

*а; *Ь;

int int int

х = у= z =

cat(17,19); cat(17, {)); cat ({), {)) ;

При

попытке

обратиться

к

optional,

в

котором

не

хранится

значение,

ре­

зультат

является

неопределенным;

исключение

при

этом

не

генерируется.

Та­

ким

образом,

optional

не

гарантирует

безопасность

с

точки

зрения

типов.

13.5.3.

any

any

может

содержать

произвольный

тип

и

при

этом

знает,

какой

тип

(если

таковой

есть)

он

содержит.

Это,

по

сути,

неограниченная

версия

variant:

any {

compose_message(istream&

s)

 

 

string

mess;

 

 

 

 

 

/ /

. . .

Чтение s

и

составление сообщения ...

if

(no_proЫems)

 

 

 

 

 

 

return

mess;

 

 

//

Возврат

string

else

 

 

 

 

 

 

 

 

return

error

 

numЬer;

//

Возврат

int

Когда

вы

присваиваете

или

инициализируете

any

значением,

объект

запо­

минает тип этого значения. Позже мы можем узнать,

значение any, и извлечь это значение. Например:

какой

именно

тип

имеет

auto m string&

=

s

compose_message(cin)); = any_cast<string>(m);

cout

<<

s;

Если

мы

пытаемся

получить

доступ

к

any

с

хранимым

типом,

отличным

от ожидаемого, генерируется исключение bad_ any_ acces s.

собы доступа к any, которые не полагаются на исключения.

Есть

также

спо­