Читаем Параллельное программирование на С++ в действии полностью

Еще один нюанс имеет отношение к использованию ссылок на r-значения в качестве параметров шаблона функции: если параметр функции — ссылка на r-значение типа параметра шаблона, механизм автоматического выведения типа аргумента шаблона заключает, что тип — это ссылка на l-значение, если функции передано l-значение, или обычный не-ссылочный тип, если передано r-значение. Фраза получилась довольно запутанной, поэтому приведём пример. Рассмотрим такую функцию:

template

void foo(T&& t) {}

Если при вызове передать ей r-значение, как показано ниже, то в качестве T выводится тип этого значения:

foo(42);

foo(3.14159);

fоо(std::string());

Но если вызвать foo, передав l-значение, то механизм выведения типа решит, что T — ссылка на l-значение:

int i = 42;

foo(i);

Поскольку объявлено, что параметр функции имеет тип T&&, то получается, что это ссылка на ссылку, и такая конструкция трактуется как обычная одинарная ссылка. Таким образом, сигнатура функции foo() такова:

void foo(int& t);

Это позволяет одному шаблону функции принимать параметры, являющиеся как l-, так и r-значениями. В частности, это используется в конструкторе std::thread (см. разделы 2.1 и 2.2), чтобы в случае, когда переданный допускающий вызов объект является r-значением, его можно было бы не копировать, а переместить во внутреннюю память.

<p>А.2. Удаленные функции</p>

Иногда операция копирования класса лишена смысла. Типичный пример — std::mutex. Действительно, что должно было бы получиться в результате копирования мьютекса? Другой пример — std::unique_lock<>, экземпляр этого класса является единственным владельцем удерживаемой им блокировки. Честное копирование в этом случае означало бы, что у блокировки два владельца, а это противоречит определению. Передача владения, описанная в разделе А.1.2, имеет смысл, но это не копирование. Уверен, вы назовете и другие примеры.

Стандартная идиома предотвращения копирования класса хорошо известна — объявить копирующий конструктор и копирующий оператор присваивания закрытыми и не предоставлять их реализации. Если теперь какой-нибудь внешний по отношению к классу код попытается скопировать объект такого класса, то произойдёт ошибка на этапе компиляции, а если то же самое попытается сделать член класса или его друг, — то ошибка на этапе компоновки (так как реализации отсутствуют):

class no_copies {

public:

 no_copies(){}

private:

 no_copies(no_copies const&); ←Реализаций нет

 no_copies& operator=(no_copies const&);

};

no_copies a; ←He компилируется

no_copies b(a);

Комитет, разрабатывавший стандарт C++11, конечно, знал об этой идиоме, но счел ее не совсем честным приёмом. Поэтому было решено предоставить более общий механизм, применимый и к другим случаям: объявить функцию удаленной, включив в ее объявление конструкцию = delete. Тогда класс no_copies можно записать в виде:

class no_copies {

public:

 no_copies() {}

 no_copies(no_copies const&) = delete;

 no_copies& operator=(no_copies const&) = delete;

};

Это гораздо нагляднее и четко выражает намерения автора. Кроме того, компилятор может в этом случае выдать более понятное сообщение об ошибке, и к тому же при попытке скопировать объект внутри функции-члена класса ошибка произойдёт уже на этапе компиляции, а не компоновки.

Если, удалив копирующие конструктор и оператор присваивания, вы явно напишете перемещающие конструктор и оператор присваивания, то класс будет допускать только перемещение — как, например, std::thread и std::unique_lock<>. В следующем листинге приведен пример такого класса.

Листинг А.2. Простой тип, допускающий только перемещение

class move_only {

 std::unique_ptr data;

public:

 move_only(const move_only&) = delete;

 move_only(move_only&& other):

  data(std::move(other.data)) {}

 move_only& operator=(const move_only&) = delete;

 move_only& operator=(move_only&& other) {

  data = std::move(other.data);

  return *this;

 }

};

move_only m1;     │Ошибка, копирующий конструктор объявлен

move_only m2(m1);←┘удаленным

move_only m3(std::move(m1));←┐правильно, имеется переме-

                             │щающий конструктор

Перейти на страницу:

Похожие книги

1С: Бухгалтерия 8 с нуля
1С: Бухгалтерия 8 с нуля

Книга содержит полное описание приемов и методов работы с программой 1С:Бухгалтерия 8. Рассматривается автоматизация всех основных участков бухгалтерии: учет наличных и безналичных денежных средств, основных средств и НМА, прихода и расхода товарно-материальных ценностей, зарплаты, производства. Описано, как вводить исходные данные, заполнять справочники и каталоги, работать с первичными документами, проводить их по учету, формировать разнообразные отчеты, выводить данные на печать, настраивать программу и использовать ее сервисные функции. Каждый урок содержит подробное описание рассматриваемой темы с детальным разбором и иллюстрированием всех этапов.Для широкого круга пользователей.

Алексей Анатольевич Гладкий

Программирование, программы, базы данных / Программное обеспечение / Бухучет и аудит / Финансы и бизнес / Книги по IT / Словари и Энциклопедии
1С: Управление торговлей 8.2
1С: Управление торговлей 8.2

Современные торговые предприятия предлагают своим клиентам широчайший ассортимент товаров, который исчисляется тысячами и десятками тысяч наименований. Причем многие позиции могут реализовываться на разных условиях: предоплата, отсрочка платежи, скидка, наценка, объем партии, и т.д. Клиенты зачастую делятся на категории – VIP-клиент, обычный клиент, постоянный клиент, мелкооптовый клиент, и т.д. Товарные позиции могут комплектоваться и разукомплектовываться, многие товары подлежат обязательной сертификации и гигиеническим исследованиям, некондиционные позиции необходимо списывать, на складах периодически должна проводиться инвентаризация, каждая компания должна иметь свою маркетинговую политику и т.д., вообщем – современное торговое предприятие представляет живой организм, находящийся в постоянном движении.Очевидно, что вся эта кипучая деятельность требует автоматизации. Для решения этой задачи существуют специальные программные средства, и в этой книге мы познакомим вам с самым популярным продуктом, предназначенным для автоматизации деятельности торгового предприятия – «1С Управление торговлей», которое реализовано на новейшей технологической платформе версии 1С 8.2.

Алексей Анатольевич Гладкий

Финансы / Программирование, программы, базы данных