C++14

Поделись знанием:
Перейти к: навигация, поиск

C++14 — неофициальное название последней версии стандарта C++ ISO/IEC JTC1 (полное название: «International Standard ISO/IEC 14882:2014(E) Programming Language C++»)[1]. C++14 можно рассматривать как небольшое расширение над C++11, содержащее в основном исправления ошибок и небольшие улучшения. Комитет разработки нового стандарта опубликовал черновик N3690 15 мая 2013[2]. Рабочая версия черновика N3936 была опубликована 2 марта 2014 года, заключительный период голосования закрыт 15 августа 2014 года, а результат (единогласное одобрение) был объявлен 18 августа 2014 года[3].

Поскольку разработка стандарта была длительной, а год выпуска итоговой версии не был определён, в ходе разработки также использовалось имя «C++1y», аналогично тому, как стандарт C++11 до его выпуска называли «C++0x» (выпуск этой версии ожидался до 2010 года).

Описанные ниже возможности языка соответствуют [www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3797.pdf рабочему черновику N3797]. В них могут быть небольшие различия по сравнению с [isocpp.org/blog/2014/02/trip-report окончательной версией стандарта].





Изменения в языке

В этом разделе приведены новые возможности ядра языка в C++14.

Вывод типа возвращаемого значения для функций

C++11 позволяет выводить тип возвращаемых значений для лямбда-функций из типа возвращаемого выражения. C++14 расширяет эту возможность на все функции. Новый стандарт также описывает вывод типов для лямбда-функций, с видом, отличным от return expression;[4].

Для того, чтобы использовать автоматический вывод типа возвращаемого значения, функция должна быть объявлена с типом auto в качестве типа возвращаемого значения, но без хвостового спецификатора типа возвращаемого значения из C++11:

auto DeduceReturnType(); // тип возвращаемого значение будет определён позже.

Если в теле функции в разных местах возвращаются несколько выражений, все эти выражения должны иметь общий выводимый тип[5].

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

В таких функциях возможно использовать рекурсию, но рекурсивный вызов должен выполняться хотя бы после одного возврата значения в этой функции[5]:

auto Correct(int i) {
 if (i == 1)
   return i; // в качестве типа возвращаемого значения выводится int
 else
   return Correct(i-1)+i; // теперь можно вызывать
}

auto Wrong(int i) {
 if(i != 1)
   return Wrong(i-1)+i; // неподходящее место для рекурсии. Нет предшествующего возврата.
 else
   return i; // в качестве типа возвращаемого значения выводится int
}

Альтернативный вывод типа при объявлении

В C++11 были добавлены два способа вывода типов. auto позволял создавать переменные с типом на основе присваиваемого выражения. decltype позволял определить результирующий тип произвольного выражения. Однако типы, выводимые decltype и auto, отличались между собой. В частности, auto всегда выводит не-ссылочный тип, как если бы был обработан std::remove_reference, тогда как auto&& всегда выводит ссылочный тип. Тем не менее, результатом decltype может быть как ссылочный тип, так и не-ссылочный, в зависимости обрабатываемого выражения[4]:

int i;
int&& f();
auto x3a = i; // decltype(x3a) - int
decltype(i) x3d = i; // decltype(x3d) - int
auto x4a = (i); // decltype(x4a) - int
decltype((i)) x4d = (i); // decltype(x4d) - int&
auto x5a = f(); // decltype(x5a) - int
decltype(f()) x5d = f(); // decltype(x5d) - int&&

В C++14 добавлен синтаксис decltype(auto). Этот синтаксис позволяет использовать правила decltype для объявлений auto.

Синтаксис decltype(auto) также можно использовать для вывода типов возвращаемых значений, если указать decltype(auto) вместо auto на месте типа возвращаемого значения функции[5].

Уменьшение ограничений на константные выражения

В C++11 представлена концепция constexpr-функций: функций, которые могут быть выполнены во время компиляции. Возвращаемые ими значения могут использоваться в операциях, где требуется константное выражение, например, в качестве аргумента шаблона. Тем не менее, в C++11 constexpr-функции могут содержать только одно возвращаемое выражение (а также static_assert и несколько других объявлений).

В C++14 эти ограничения частично сняты. Constexpr-функции теперь могут содержать следующие элементы[4]:

  • Любые объявления, кроме:
    • static или thread_local переменных;
    • объявлений переменных без инициализаторов.
  • Условные выражения ветвления if и switch.
  • Все операторы циклов, в том числе for для диапазонов.
  • Выражения, изменяющие значения объектов, если время жизни этих объектов началось в constexpr-функции. К этому относятся также вызовы любых не-const constexpr нестатических функций-членов.

goto-выражения не допускаются в constexpr-функциях C++14.

Ограничения на вызов не-constexpr-функций остаются в силе. Таким образом, если используется for для диапазонов, функции begin и end контейнеров должны быть перегружены как constexpr. Для встроенного типа std::initializer_list функции begin/end определены как constexpr, как локально, так и глобально.

Кроме того, в C++11 все нестатические методы, объявленные с constexpr, неявно считались const-функциями по отношению к this. Это ограничение снято; нестатические методы теперь могут быть не const[6]. Тем не менее, как упомянуто ранее, не-const constexpr-метод может изменить поля класса только в том случае, если время жизни этого объекта началось в ходе вычисления константного выражения.

Шаблоны переменных

В предыдущих версиях C++ шаблонизация применялась только для функций и классов. C++14 позволяет создавать шаблонные переменные.

template<typename T>
constexpr T pi = T(3.1415926535897932385);

// Usual specialization rules apply:
template<>
constexpr const char* pi<const char*> = "pi";

В этом примере определён шаблон переменной pi, к которому можно обратиться, чтобы получить значение числа пи для различных типов (например, 3, при чтении целого типа; наиболее близкое значение к float , double или long double при чтении как float , double или long double , соответственно, и т. д.).

К таким объявлениям и определениям относятся обычные правила шаблонов, в том числе правила специализации[7][8].

Агрегатная инициализация классов с инициализаторами полей

В C++11 были добавлены инициализаторы полей классов — выражения, применяемые к полям на уровне класса, если конструктор их не инициализирует самостоятельно. Определение агрегатов было изменено, чтобы явно исключить все классы с инициализаторами членов, поэтому для них агрегатная инициализация была невозможна.

C++14 снимает это ограничение[4] и разрешает агрегатную инициализацию классов с инициализаторами полей. Если список инициализаторов в фигурных скобках не предоставляет значение для этого аргумента, то работу на себя возьмёт инициализатор поля[9].

Литералы двоичных чисел

Числовые литералы в C++14 можно указать в двоичной форме[4]. Синтаксис использует префиксы 0b или 0B. Схожий синтаксис также используется в Java, Python, Perl и D.

Разделители разрядов

В C++14 можно использовать апостроф для произвольного разделения разрядов в числовых литералах[10]. В некоторых случаях это упрощает восприятие больших числовых констант в коде и улучшает читаемость кода.

auto integer_literal = 1’000’000;
auto floating_point_literal = 0.000’015’3;
auto binary_literal = 0b0100’1100’0110;
auto silly_example = 1’0’0’000’00;

Обобщённые лямбда-функции

В C++11 параметры лямбда-функций требовалось объявлять с указанием конкретных типов. C++14 снимает это ограничение и позволяет объявлять параметры лямбда-функций со спецификатором типа auto[7].

auto lambda = [](auto x, auto y) {return x + y;};

Выведение типов параметров обобщённых лямбда-функций выполняется по правилам, схожим с выведением типов для auto-переменных (но не является полностью идентичным). Приведённый выше код эквивалентен следующему[11]:

struct unnamed_lambda
{
 template<typename T, typename U>
 auto operator()(T x, U y) const {return x + y;}
};
auto lambda = unnamed_lambda();

Захват выражений для лямбда-функций

Лямбда-функции C++11 позволяют захватывать переменные, объявленные во внешней области видимости, путём передачи по ссылке или по значению. Это означает, что нельзя захватить по значению переменные типов, допускающих только перемещение (но не допускающих копирования)[12]. C++14 позволяет захватывать переменные с инициализацией произвольным выражением. Благодаря этому возможно захватывать переменные с перемещением значения и объявлять переменные с именами, не объявленными в более высоких областях видимости[7].

Захват выражений осуществляется с помощью инициализаторов:

auto lambda = [value = 1] {return value;};

Лямбда-функция lambda вернёт 1, так как для параметра value сработал соответствующий инициализатор. Тип захватываемого параметра выводится из типа инициализатора, подобно объявлению переменной со спецификатором auto.

Эту возможность можно использовать для захвата с перемещением при помощи стандартной функции std::move:

auto ptr = make_unique<int>(10);
auto lambda = [value = std::move(ptr)] {return *value;};

Атрибут [[deprecated]]

Атрибут deprecated позволяет отмечать сущности как устаревшие. Обращение к этим сущностям по-прежнему возможно, но при компиляции выводится предупреждение. В качестве аргумента deprecated может выступать строковый литерал, объясняющий причину устаревания и/или возможную замену.

[[deprecated]] int f();

[[deprecated("g() не является потоко-безопасным. Используйте h() вместо g()")]]
void g( int& x );

void h( int& x );

void test() {
  int a = f(); // warning: 'f' is deprecated
  g(a); // warning: 'g' is deprecated: g() не является потоко-безопасным. Используйте h() вместо g()
}

Новые функции стандартной библиотеки

Разделяемые мьютексы и блокировки

В C++14 добавлены разделяемые (shared) мьютексы и новый тип блокировки для таких мьютексов[13][14].

Гетерогенный поиск в ассоциативных контейнерах

Стандартная библиотека C++ определяет четыре ассоциативных класса-контейнера. Эти классы позволяют пользователю искать значения на основе значения этого типа. Контейнеры map позволяют пользователю указать ключ и значение, при этом поиск производится по ключу и возвращает значение. Тем не менее, поиск всегда выполнялся по конкретному типу ключа, будь то ключ, как в map или само значение, как в set.

C++14 позволяет индексировать ассоциативные контейнеры значением произвольного типа при условии, что имеется перегруженный оператор сравнения, который может сравнивать значение этого типа со значением типа ключа контейнера[15]. Это позволяет индексировать map-контейнеры с типом ключа std::string выражениями типа const char* с использованием перегруженного оператора сравнения operator<.

Для сохранения обратной совместимости, гетерогенный поиск допускается только тогда, когда компаратор, передаваемый ассоциативному контейнеру, поддерживает такой поиск. Классы стандартной библиотеки std::less (по умолчанию для set- и map-контейнеров) и std::greater позволяют осуществлять гетерогенный поиск[16].

Стандартные пользовательские литералы

В C++11 описан синтаксис определяемых пользователем литеральных суффиксов, но ни один из них не используется в стандартной библиотеке. C++14 добавляет следующие стандартные литералы[15]:

  • «s» для создания различных std::basic_string типов.
  • «h», «min», «s», «ms», «us» и «ns» для создания соответствующих временных интервалов std::chrono::duration.
string str = "hello world"s;
chrono::duration dur = 60s;

Два литерала «s» не влияют друг на друга, поскольку строковой литерал работает только со строками, а секундный действует только на числа[17].

Адресация к кортежам по типу

std::tuple, введённый в C++11, позволяет агрегировать несколько типизированных значений, которые будут проиндексированы во время компиляции. C++14 расширяет функциональность кортежей для возможности обращения к элементам кортежа не только по индексу, но и по типу[15]. Если кортеж содержит более одного элемента запрашиваемого типа, поиск приведёт к ошибке времени компиляции[18]:

tuple<string, string, int> t("foo", "bar", 7);
int i = get<int>(t); // i == 7
int j = get<2>(t); // то же, что и раньше: j == 7
string s = get<string>(t); // ошибка времени компиляции из-за неоднозначности

Прочие изменения стандартной библиотеки

std::make_unique можно использовать так же, как и std::make_shared для объектов std::unique_ptr[7].

Для std::integral_constant добавлен перегруженный operator(), возвращающий константное значение[15].

По аналогии с глобальными функциями std::begin/std::end добавлены функции std::cbegin/std::cend, которые возвращают константные итераторы на начало и конец диапазона.

Напишите отзыв о статье "C++14"

Примечания

  1. [www.iso.org/iso/home/store/catalogue_tc/catalogue_detail.htm?csnumber=64029 ISO/IEC 14882:2014 — Information technology — Programming languages — C++]. ISO (14 January 2014).
  2. [www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3690.pdf Committee Draft, Standard for Programming Language C++] (PDF). ISO (15 мая 2013).
  3. Sutter, Herb (August 18, 2014), [isocpp.org/blog/2014/08/we-have-cpp14 We have C++14!], <isocpp.org/blog/2014/08/we-have-cpp14>. Проверено 18 августа 2014. 
  4. 1 2 3 4 5 Wong, Michael [www.ibm.com/developerworks/community/blogs/5894415f-be62-4bc0-81c5-3956e82276f3/entry/the_view_form_the_c_standard_meeting_april_2013_part_3?lang=en The View from the C++ Standard meeting April 2013 Part 3]. C/C++ Cafe (30 апреля 2013). Проверено 14 июня 2013.
  5. 1 2 3 Merrill, Jason [www.open-std.org/JTC1/SC22/WG21/docs/papers/2013/n3638.html N3638 Return type deduction for normal functions (Revision 5)] (17 апреля 2013). Проверено 14 июня 2013.
  6. Smith, Richard [www.open-std.org/JTC1/SC22/WG21/docs/papers/2013/n3652.html N3652 Relaxing constraints on constexpr functions] (18 апреля 2013).
  7. 1 2 3 4 Саттер, Герб [isocpp.org/blog/2013/04/trip-report-iso-c-spring-2013-meeting Trip Report: ISO C++ Spring 2013 Meeting] (20 апреля 2013). Проверено 14 июня 2013.
  8. Dos Reis, Gabriel [www.open-std.org/JTC1/SC22/WG21/docs/papers/2013/n3651.pdf N3651 Variable Templates (Revision 1)] (PDF) (19 апреля 2013).
  9. [www.open-std.org/JTC1/SC22/WG21/docs/papers/2013/n3653.html N3653 Member initializers and aggregates] (17 апреля 2013).
  10. [www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3781.pdf N3781 Single-Quotation-Mark as a Digit Separator] (25 September 2013).
  11. [www.open-std.org/JTC1/SC22/WG21/docs/papers/2013/n3649.html N3649 Generic (Polymorphic) Lambda Expressions (Revision 3)] (19 апреля 2013).
  12. [stackoverflow.com/questions/8640393/move-capture-in-lambda Move capture in Lambda].
  13. Wong, Michael [www.ibm.com/developerworks/community/blogs/5894415f-be62-4bc0-81c5-3956e82276f3/entry/the_view_form_the_c_standard_meeting_april_2013_part_3?lang=en The View from the C++ Standard meeting April 2013 Part 3]. C/C++ Cafe (30 апреля 2013). Проверено 14 июня 2013.
  14. [www.open-std.org/JTC1/SC22/WG21/docs/papers/2013/n3659.html N3659 Shared locking in C++ (Revision 2)] (19 апреля 2013).
  15. 1 2 3 4 Wong, Michael [www.ibm.com/developerworks/community/blogs/5894415f-be62-4bc0-81c5-3956e82276f3/entry/the_view_form_the_c_standrd_meeting_april_2013_part_2?lang=en The View from the C++ Standard meeting April 2013 Part 2]. C/C++ Cafe (26 апреля 2013). Проверено 14 июня 2013.
  16. [www.open-std.org/JTC1/SC22/WG21/docs/papers/2013/n3657.htm N3657 Adding heterogeneous comparison lookup to associative containers (rev 4)] (19 марта 2013).
  17. Peter, Sommerlad [www.open-std.org/JTC1/SC22/WG21/docs/papers/2013/n3642.pdf N3642 User-defined Literals for Standard Library Types (part 1 - version 4)] (PDF) (18 апреля 2013).
  18. Spertus, Mike [www.open-std.org/JTC1/SC22/WG21/docs/papers/2013/n3670.html N3670 Wording for Addressing Tuples by Type: Revision 2] (19 апреля 2013).

Отрывок, характеризующий C++14

Граф замахал руками и, ничего не сказав, вышел из комнаты.
– Папа! об чем вы это? – сказала ему Наташа, вслед за ним вошедшая в комнату матери.
– Ни о чем! Тебе что за дело! – сердито проговорил граф.
– Нет, я слышала, – сказала Наташа. – Отчего ж маменька не хочет?
– Тебе что за дело? – крикнул граф. Наташа отошла к окну и задумалась.
– Папенька, Берг к нам приехал, – сказала она, глядя в окно.


Берг, зять Ростовых, был уже полковник с Владимиром и Анной на шее и занимал все то же покойное и приятное место помощника начальника штаба, помощника первого отделения начальника штаба второго корпуса.
Он 1 сентября приехал из армии в Москву.
Ему в Москве нечего было делать; но он заметил, что все из армии просились в Москву и что то там делали. Он счел тоже нужным отпроситься для домашних и семейных дел.
Берг, в своих аккуратных дрожечках на паре сытых саврасеньких, точно таких, какие были у одного князя, подъехал к дому своего тестя. Он внимательно посмотрел во двор на подводы и, входя на крыльцо, вынул чистый носовой платок и завязал узел.
Из передней Берг плывущим, нетерпеливым шагом вбежал в гостиную и обнял графа, поцеловал ручки у Наташи и Сони и поспешно спросил о здоровье мамаши.
– Какое теперь здоровье? Ну, рассказывай же, – сказал граф, – что войска? Отступают или будет еще сраженье?
– Один предвечный бог, папаша, – сказал Берг, – может решить судьбы отечества. Армия горит духом геройства, и теперь вожди, так сказать, собрались на совещание. Что будет, неизвестно. Но я вам скажу вообще, папаша, такого геройского духа, истинно древнего мужества российских войск, которое они – оно, – поправился он, – показали или выказали в этой битве 26 числа, нет никаких слов достойных, чтоб их описать… Я вам скажу, папаша (он ударил себя в грудь так же, как ударял себя один рассказывавший при нем генерал, хотя несколько поздно, потому что ударить себя в грудь надо было при слове «российское войско»), – я вам скажу откровенно, что мы, начальники, не только не должны были подгонять солдат или что нибудь такое, но мы насилу могли удерживать эти, эти… да, мужественные и древние подвиги, – сказал он скороговоркой. – Генерал Барклай до Толли жертвовал жизнью своей везде впереди войска, я вам скажу. Наш же корпус был поставлен на скате горы. Можете себе представить! – И тут Берг рассказал все, что он запомнил, из разных слышанных за это время рассказов. Наташа, не спуская взгляда, который смущал Берга, как будто отыскивая на его лице решения какого то вопроса, смотрела на него.
– Такое геройство вообще, каковое выказали российские воины, нельзя представить и достойно восхвалить! – сказал Берг, оглядываясь на Наташу и как бы желая ее задобрить, улыбаясь ей в ответ на ее упорный взгляд… – «Россия не в Москве, она в сердцах се сынов!» Так, папаша? – сказал Берг.
В это время из диванной, с усталым и недовольным видом, вышла графиня. Берг поспешно вскочил, поцеловал ручку графини, осведомился о ее здоровье и, выражая свое сочувствие покачиваньем головы, остановился подле нее.
– Да, мамаша, я вам истинно скажу, тяжелые и грустные времена для всякого русского. Но зачем же так беспокоиться? Вы еще успеете уехать…
– Я не понимаю, что делают люди, – сказала графиня, обращаясь к мужу, – мне сейчас сказали, что еще ничего не готово. Ведь надо же кому нибудь распорядиться. Вот и пожалеешь о Митеньке. Это конца не будет?
Граф хотел что то сказать, но, видимо, воздержался. Он встал с своего стула и пошел к двери.
Берг в это время, как бы для того, чтобы высморкаться, достал платок и, глядя на узелок, задумался, грустно и значительно покачивая головой.
– А у меня к вам, папаша, большая просьба, – сказал он.
– Гм?.. – сказал граф, останавливаясь.
– Еду я сейчас мимо Юсупова дома, – смеясь, сказал Берг. – Управляющий мне знакомый, выбежал и просит, не купите ли что нибудь. Я зашел, знаете, из любопытства, и там одна шифоньерочка и туалет. Вы знаете, как Верушка этого желала и как мы спорили об этом. (Берг невольно перешел в тон радости о своей благоустроенности, когда он начал говорить про шифоньерку и туалет.) И такая прелесть! выдвигается и с аглицким секретом, знаете? А Верочке давно хотелось. Так мне хочется ей сюрприз сделать. Я видел у вас так много этих мужиков на дворе. Дайте мне одного, пожалуйста, я ему хорошенько заплачу и…
Граф сморщился и заперхал.
– У графини просите, а я не распоряжаюсь.
– Ежели затруднительно, пожалуйста, не надо, – сказал Берг. – Мне для Верушки только очень бы хотелось.
– Ах, убирайтесь вы все к черту, к черту, к черту и к черту!.. – закричал старый граф. – Голова кругом идет. – И он вышел из комнаты.
Графиня заплакала.
– Да, да, маменька, очень тяжелые времена! – сказал Берг.
Наташа вышла вместе с отцом и, как будто с трудом соображая что то, сначала пошла за ним, а потом побежала вниз.
На крыльце стоял Петя, занимавшийся вооружением людей, которые ехали из Москвы. На дворе все так же стояли заложенные подводы. Две из них были развязаны, и на одну из них влезал офицер, поддерживаемый денщиком.
– Ты знаешь за что? – спросил Петя Наташу (Наташа поняла, что Петя разумел: за что поссорились отец с матерью). Она не отвечала.
– За то, что папенька хотел отдать все подводы под ранепых, – сказал Петя. – Мне Васильич сказал. По моему…
– По моему, – вдруг закричала почти Наташа, обращая свое озлобленное лицо к Пете, – по моему, это такая гадость, такая мерзость, такая… я не знаю! Разве мы немцы какие нибудь?.. – Горло ее задрожало от судорожных рыданий, и она, боясь ослабеть и выпустить даром заряд своей злобы, повернулась и стремительно бросилась по лестнице. Берг сидел подле графини и родственно почтительно утешал ее. Граф с трубкой в руках ходил по комнате, когда Наташа, с изуродованным злобой лицом, как буря ворвалась в комнату и быстрыми шагами подошла к матери.
– Это гадость! Это мерзость! – закричала она. – Это не может быть, чтобы вы приказали.
Берг и графиня недоумевающе и испуганно смотрели на нее. Граф остановился у окна, прислушиваясь.
– Маменька, это нельзя; посмотрите, что на дворе! – закричала она. – Они остаются!..
– Что с тобой? Кто они? Что тебе надо?
– Раненые, вот кто! Это нельзя, маменька; это ни на что не похоже… Нет, маменька, голубушка, это не то, простите, пожалуйста, голубушка… Маменька, ну что нам то, что мы увезем, вы посмотрите только, что на дворе… Маменька!.. Это не может быть!..
Граф стоял у окна и, не поворачивая лица, слушал слова Наташи. Вдруг он засопел носом и приблизил свое лицо к окну.
Графиня взглянула на дочь, увидала ее пристыженное за мать лицо, увидала ее волнение, поняла, отчего муж теперь не оглядывался на нее, и с растерянным видом оглянулась вокруг себя.
– Ах, да делайте, как хотите! Разве я мешаю кому нибудь! – сказала она, еще не вдруг сдаваясь.
– Маменька, голубушка, простите меня!
Но графиня оттолкнула дочь и подошла к графу.
– Mon cher, ты распорядись, как надо… Я ведь не знаю этого, – сказала она, виновато опуская глаза.
– Яйца… яйца курицу учат… – сквозь счастливые слезы проговорил граф и обнял жену, которая рада была скрыть на его груди свое пристыженное лицо.
– Папенька, маменька! Можно распорядиться? Можно?.. – спрашивала Наташа. – Мы все таки возьмем все самое нужное… – говорила Наташа.
Граф утвердительно кивнул ей головой, и Наташа тем быстрым бегом, которым она бегивала в горелки, побежала по зале в переднюю и по лестнице на двор.
Люди собрались около Наташи и до тех пор не могли поверить тому странному приказанию, которое она передавала, пока сам граф именем своей жены не подтвердил приказания о том, чтобы отдавать все подводы под раненых, а сундуки сносить в кладовые. Поняв приказание, люди с радостью и хлопотливостью принялись за новое дело. Прислуге теперь это не только не казалось странным, но, напротив, казалось, что это не могло быть иначе, точно так же, как за четверть часа перед этим никому не только не казалось странным, что оставляют раненых, а берут вещи, но казалось, что не могло быть иначе.
Все домашние, как бы выплачивая за то, что они раньше не взялись за это, принялись с хлопотливостью за новое дело размещения раненых. Раненые повыползли из своих комнат и с радостными бледными лицами окружили подводы. В соседних домах тоже разнесся слух, что есть подводы, и на двор к Ростовым стали приходить раненые из других домов. Многие из раненых просили не снимать вещей и только посадить их сверху. Но раз начавшееся дело свалки вещей уже не могло остановиться. Было все равно, оставлять все или половину. На дворе лежали неубранные сундуки с посудой, с бронзой, с картинами, зеркалами, которые так старательно укладывали в прошлую ночь, и всё искали и находили возможность сложить то и то и отдать еще и еще подводы.
– Четверых еще можно взять, – говорил управляющий, – я свою повозку отдаю, а то куда же их?
– Да отдайте мою гардеробную, – говорила графиня. – Дуняша со мной сядет в карету.
Отдали еще и гардеробную повозку и отправили ее за ранеными через два дома. Все домашние и прислуга были весело оживлены. Наташа находилась в восторженно счастливом оживлении, которого она давно не испытывала.
– Куда же его привязать? – говорили люди, прилаживая сундук к узкой запятке кареты, – надо хоть одну подводу оставить.
– Да с чем он? – спрашивала Наташа.
– С книгами графскими.
– Оставьте. Васильич уберет. Это не нужно.
В бричке все было полно людей; сомневались о том, куда сядет Петр Ильич.
– Он на козлы. Ведь ты на козлы, Петя? – кричала Наташа.
Соня не переставая хлопотала тоже; но цель хлопот ее была противоположна цели Наташи. Она убирала те вещи, которые должны были остаться; записывала их, по желанию графини, и старалась захватить с собой как можно больше.


Во втором часу заложенные и уложенные четыре экипажа Ростовых стояли у подъезда. Подводы с ранеными одна за другой съезжали со двора.
Коляска, в которой везли князя Андрея, проезжая мимо крыльца, обратила на себя внимание Сони, устраивавшей вместе с девушкой сиденья для графини в ее огромной высокой карете, стоявшей у подъезда.
– Это чья же коляска? – спросила Соня, высунувшись в окно кареты.
– А вы разве не знали, барышня? – отвечала горничная. – Князь раненый: он у нас ночевал и тоже с нами едут.
– Да кто это? Как фамилия?
– Самый наш жених бывший, князь Болконский! – вздыхая, отвечала горничная. – Говорят, при смерти.
Соня выскочила из кареты и побежала к графине. Графиня, уже одетая по дорожному, в шали и шляпе, усталая, ходила по гостиной, ожидая домашних, с тем чтобы посидеть с закрытыми дверями и помолиться перед отъездом. Наташи не было в комнате.
– Maman, – сказала Соня, – князь Андрей здесь, раненый, при смерти. Он едет с нами.
Графиня испуганно открыла глаза и, схватив за руку Соню, оглянулась.
– Наташа? – проговорила она.
И для Сони и для графини известие это имело в первую минуту только одно значение. Они знали свою Наташу, и ужас о том, что будет с нею при этом известии, заглушал для них всякое сочувствие к человеку, которого они обе любили.
– Наташа не знает еще; но он едет с нами, – сказала Соня.
– Ты говоришь, при смерти?
Соня кивнула головой.
Графиня обняла Соню и заплакала.
«Пути господни неисповедимы!» – думала она, чувствуя, что во всем, что делалось теперь, начинала выступать скрывавшаяся прежде от взгляда людей всемогущая рука.
– Ну, мама, все готово. О чем вы?.. – спросила с оживленным лицом Наташа, вбегая в комнату.
– Ни о чем, – сказала графиня. – Готово, так поедем. – И графиня нагнулась к своему ридикюлю, чтобы скрыть расстроенное лицо. Соня обняла Наташу и поцеловала ее.
Наташа вопросительно взглянула на нее.
– Что ты? Что такое случилось?
– Ничего… Нет…
– Очень дурное для меня?.. Что такое? – спрашивала чуткая Наташа.
Соня вздохнула и ничего не ответила. Граф, Петя, m me Schoss, Мавра Кузминишна, Васильич вошли в гостиную, и, затворив двери, все сели и молча, не глядя друг на друга, посидели несколько секунд.
Граф первый встал и, громко вздохнув, стал креститься на образ. Все сделали то же. Потом граф стал обнимать Мавру Кузминишну и Васильича, которые оставались в Москве, и, в то время как они ловили его руку и целовали его в плечо, слегка трепал их по спине, приговаривая что то неясное, ласково успокоительное. Графиня ушла в образную, и Соня нашла ее там на коленях перед разрозненно по стене остававшимися образами. (Самые дорогие по семейным преданиям образа везлись с собою.)
На крыльце и на дворе уезжавшие люди с кинжалами и саблями, которыми их вооружил Петя, с заправленными панталонами в сапоги и туго перепоясанные ремнями и кушаками, прощались с теми, которые оставались.
Как и всегда при отъездах, многое было забыто и не так уложено, и довольно долго два гайдука стояли с обеих сторон отворенной дверцы и ступенек кареты, готовясь подсадить графиню, в то время как бегали девушки с подушками, узелками из дому в кареты, и коляску, и бричку, и обратно.
– Век свой все перезабудут! – говорила графиня. – Ведь ты знаешь, что я не могу так сидеть. – И Дуняша, стиснув зубы и не отвечая, с выражением упрека на лице, бросилась в карету переделывать сиденье.
– Ах, народ этот! – говорил граф, покачивая головой.
Старый кучер Ефим, с которым одним только решалась ездить графиня, сидя высоко на своих козлах, даже не оглядывался на то, что делалось позади его. Он тридцатилетним опытом знал, что не скоро еще ему скажут «с богом!» и что когда скажут, то еще два раза остановят его и пошлют за забытыми вещами, и уже после этого еще раз остановят, и графиня сама высунется к нему в окно и попросит его Христом богом ехать осторожнее на спусках. Он знал это и потому терпеливее своих лошадей (в особенности левого рыжего – Сокола, который бил ногой и, пережевывая, перебирал удила) ожидал того, что будет. Наконец все уселись; ступеньки собрались и закинулись в карету, дверка захлопнулась, послали за шкатулкой, графиня высунулась и сказала, что должно. Тогда Ефим медленно снял шляпу с своей головы и стал креститься. Форейтор и все люди сделали то же.
– С богом! – сказал Ефим, надев шляпу. – Вытягивай! – Форейтор тронул. Правый дышловой влег в хомут, хрустнули высокие рессоры, и качнулся кузов. Лакей на ходу вскочил на козлы. Встряхнуло карету при выезде со двора на тряскую мостовую, так же встряхнуло другие экипажи, и поезд тронулся вверх по улице. В каретах, коляске и бричке все крестились на церковь, которая была напротив. Остававшиеся в Москве люди шли по обоим бокам экипажей, провожая их.