C++11

Поделись знанием:
(перенаправлено с «C++0x»)
Перейти к: навигация, поиск

C++11[1][2] или ISO/IEC 14882:2011[3] (в процессе работы над стандартом носил условное наименование C++0x[4][5]) — новая версия стандарта языка C++, вместо ранее действовавшего ISO/IEC 14882:2003. Новый стандарт включает дополнения в ядре языка и расширение стандартной библиотеки, в том числе большую часть TR1 — кроме, вероятно, библиотеки специальных математических функций. Несмотря на то, что работа над стандартом уже завершена[6] — данная статья, возможно, не будет точно соответствовать конечному варианту стандарта. Разные версии (в том числе самые новые) черновика будущего стандарта наряду с некоторыми другими документами, посвящёнными стандартизации C++, публикуются на сайте комитета ISO C++[7].

ISO/IEC JTC1/SC22/WG21 Комитет Стандартизации C++ намеревался опубликовать новый стандарт в 2009 году (соответственно стандарт, который сейчас называют C++11, должен был называться C++09). Чтобы успеть, Комитет решил сосредоточиться на предложениях, поступивших до 2006, и игнорировать более новые[8].

Языки программирования, такие как C++, проходят постепенное развитие своих возможностей. Этот процесс неизбежно вызывает проблемы совместимости с уже существующим кодом. В приложении C.2 [diff.cpp03] документа [www.open-std.org/jtc1/sc22/open/n3290.html N3290] (англ. Final Draft International Standard) описаны некоторые из несовместимостей C++11 с C++03.





Содержание

Предполагаемые изменения стандарта

Как уже было сказано, изменения коснутся как ядра С++, так и его стандартной библиотеки.

При разработке каждого раздела будущего стандарта комитет использовал ряд правил:

  • поддержка стабильности языка и обеспечение совместимости с C++98 и, по возможности, с Си;
  • предпочитается введение новых возможностей через стандартную библиотеку, а не через ядро языка;
  • предпочитаются изменения, которые улучшают технику программирования;
  • совершенствовать C++ с точки зрения системного и библиотечного дизайна, вместо введения новых возможностей, полезных для отдельных приложений;
  • увеличивать типобезопасность для обеспечения безопасной альтернативы для нынешних опасных подходов;
  • увеличивать производительность и возможности работать напрямую с аппаратной частью;
  • обеспечивать решение реальных, широко распространённых проблем;
  • реализовать принцип «не платить за то, что не используешь»;
  • сделать C++ проще для изучения без удаления возможностей, используемых программистами-экспертами.

Уделяется внимание новичкам, которые всегда будут составлять большую часть программистов. Многие новички не стремятся углублять уровень владения С++, ограничиваясь его использованием при работе над узкими специфичными задачами[8]. Кроме того, учитывая универсальность С++ и обширность его использования (включая как разнообразие приложений, так и стилей программирования), даже профессионалы могут оказаться новичками при использовании новых парадигм программирования.

Расширение ядра языка

Первоочередная задача комитета — развитие ядра языка С++. Ядро значительно усовершенствовано, добавлена поддержка многопоточности, улучшена поддержка обобщённого программирования, унификация инициализации и проведены работы по повышению его производительности.

Для удобства, возможности ядра и его изменения разделены на три основные части: повышение производительности, повышение удобства и новая функциональность. Отдельные элементы могут относиться к нескольким группам, но описываться будут только в одной — наиболее подходящей.

Повышение производительности

Эти компоненты языка введены для уменьшения затрат памяти или увеличения производительности.

Ссылки на временные объекты и семантика переноса (Rvalue Reference/Move semantics)

По стандарту C++ временный объект, появившийся в результате вычисления выражения, можно передавать в функции, но только по константной ссылке (const &). Функция не в состоянии определить, можно ли рассматривать переданный объект как временный и допускающий модификацию (константный объект, который тоже может быть передан по такой ссылке, нельзя модифицировать (легально)). Это не проблема для простейших структур наподобие complex, но для сложных типов, требующих выделения-освобождения памяти, уничтожение временного объекта и создание постоянного может отнимать много времени, в то время как можно было бы просто напрямую передать указатели.

В C++11 появился новый тип ссылки — rvalue-ссылка (англ. rvalue reference). Его объявление следующее: type &&. Новые правила разрешения перегрузки позволяют использовать разные перегруженные функции для неконстантных временных объектов, обозначаемых посредством rvalues, и для всех остальных объектов. Данное нововведение позволяет реализовывать семантику переноса (Move semantics).

Например, std::vector — это простая обёртка вокруг Си-массива и переменной, хранящей его размер. Конструктор копирования std::vector::vector(const vector &x) создаст новый массив и скопирует информацию; конструктор переноса std::vector::vector(vector &&x) может просто обменяться указателями и переменными, содержащими длину.

Пример объявления.

template<class T> class vector
{
   vector (const vector &);              // Конструктор копирования (медленный)
   vector (vector &&);                   // Конструктор переноса из временного объекта (быстрый)
   vector & operator = (const vector &); // Обычное присваивание (медленное)
   vector & operator = (vector &&);      // Перенос временного объекта (быстрый)
};

Обобщённые константные выражения

В C++ всегда присутствовала концепция константных выражений. Так, выражения типа 3+4 всегда возвращали одни и те же результаты, не вызывая никаких побочных эффектов. Сами по себе константные выражения предоставляют компиляторам C++ удобные возможности по оптимизации результата компиляции. Компиляторы вычисляют результаты таких выражений только на этапе компиляции и сохраняют уже вычисленные результаты в программе. Таким образом, подобные выражения вычисляются только раз. Также существует несколько случаев, в которых стандарт языка требует использования константных выражений. Такими случаями, например, могут быть определения внешних массивов или значения перечислений (enum).


int GiveFive() {return 5;}

int some_value[GiveFive() + 7]; // создание массива 12 целых; запрещено в C++

Вышеуказанный код запрещён в C++, поскольку GiveFive() + 7 формально не является константным выражением, известным на этапе компиляции. Компилятору на тот момент просто не известно, что функция на самом деле возвращает константу во время исполнения. Причиной таких рассуждений компилятора является то, что эта функция может повлиять на состояние глобальной переменной, вызвать другую неконстантную функцию времени исполнения и т. д.

C++11 вводит ключевое слово constexpr, которое позволяет пользователю гарантировать, что или функция или конструктор объекта возвращает константу времени компиляции. Код выше может быть переписан следующим образом:

constexpr int GiveFive() {return 5;}

int some_value[GiveFive() + 7]; // создание массива 12 целых; разрешено в C++11

Такое ключевое слово позволяет компилятору понять и удостовериться в том, что GiveFive возвращает константу.

Использование constexpr порождает очень жёсткие ограничения на действия функции:

  1. такая функция должна возвращать значение;
  2. тело функции должно быть вида return выражение;
  3. выражение должно состоять из констант и/или вызовов других constexpr-функций;
  4. функция, обозначенная constexpr, не может использоваться до определения в текущей единице компиляции.

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

constexpr double accelerationOfGravity = 9.8;
constexpr double moonGravity = accelerationOfGravity / 6;

Такие переменные уже неявно считаются обозначенными ключевым словом const. В них могут содержаться только результаты константных выражений или конструкторы таких выражений.

В случае необходимости конструирования константных значений из типов, определённых пользователем, конструкторы таких типов также могут быть описаны с помощью constexpr. Конструктор константных выражений, подобно константным функциям, также должен быть определён до момента первого его использования в текущей единице компиляции. У такого конструктора должно быть пустое тело, а также такой конструктор должен инициализировать члены своего типа только константами.

Изменения в определении простых данных

В стандартном C++ только структуры, удовлетворяющие определённому набору правил, могут рассматриваться как тип простых данных (plain old data type или POD). Существуют веские причины ожидать расширения этих правил, с тем, чтобы большее число типов рассматривались как POD. Типы, удовлетворяющие этим правилам, могут использоваться в реализации объектного слоя, совместимого с C. Однако, в C++03 список этих правил чрезмерно строгий.

C++11 ослабит несколько правил, касающихся определения типов простых данных.

Класс рассматривается как тип простых данных, если он тривиальный (trivial), со стандартным размещением (standard-layout) и если типы всех его нестатических членов-данных также являются типами простых данных.

Тривиальный класс — это класс, который:

  1. содержит тривиальный конструктор по умолчанию,
  2. не содержит нетривиальных копирующих конструкторов,
  3. не содержит нетривиальных перемещающих конструкторов,
  4. не содержит нетривиальных копирующих операторов присваивания,
  5. не содержит нетривиальных перемещающих операторов присваивания,
  6. содержит тривиальный деструктор.

Класс со стандартным размещением — это класс, который:

  1. не содержит нестатических членов-данных, имеющих тип класса с нестандартным размещением (или массива элементов такого типа) или ссылочный тип,
  2. не содержит виртуальных функций,
  3. не содержит виртуальных базовых классов,
  4. имеет один и тот же вид доступности (public, private, protected) для всех нестатических членов-данных,
  5. не имеет базовых классов с нестандартным размещением,
  6. не является классом, одновременно содержащим унаследованные и неунаследованные нестатические члены-данные, или содержащим нестатические члены-данные, унаследованные сразу от нескольких базовых классов,
  7. не имеет базовых классов того же типа, что и у первого нестатического члена-данного (если таковой есть).

Ускорение компиляции

Внешние шаблоны

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

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

template class std::vector<MyClass>;

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

extern template class std::vector<MyClass>;

Данное выражение говорит компилятору не инстанцировать шаблон в данной единице трансляции.

Повышение удобства использования

Эти возможности предназначены для того, чтобы упростить использование языка. Они позволяют усилить типобезопасность, минимизировать дублирование кода, усложняют ошибочное использование кода и т. п.

Списки инициализации

Концепция списков инициализации пришла в C++ из C. Идея состоит в том, что структура или массив могут быть созданы передачей списка аргументов в порядке, соответствующем порядку определения членов структуры. Списки инициализации рекурсивны, что позволяет их использовать для массивов структур и структур, содержащих вложенные структуры.

struct Object
{
    float first;
    int second;
};

Object scalar = {0.43f, 10}; // один объект, с first=0.43f и second=10
Object anArray[] = {{13.4f, 3}, {43.28f, 29}, {5.934f, 17}}; // массив из трёх объектов

Списки инициализации очень полезны для статических списков и в тех случаях, когда требуется инициализировать структуру определённым значением. C++ также содержит конструкторы, которые могут содержать общую часть работы по инициализации объектов. Стандарт C++ позволяет использовать списки инициализации для структур и классов при условии, что те соответствуют определению простого типа данных (Plain Old Data — POD). Классы, не являющиеся POD, не могут использовать для инициализации списки инициализации, в том числе это касается и стандартных контейнеров C++, таких, как векторы.

C++11 связал концепцию списков инициализации и шаблонный класс, названный std::initializer_list. Это позволило конструкторам и другим функциям получать списки инициализации в качестве параметров. Например:

class SequenceClass
{
public:
  SequenceClass(std::initializer_list<int> list);
};

Данное описание позволяет создать SequenceClass из последовательности целых чисел следующим образом:

SequenceClass someVar = {1, 4, 5, 6};

Здесь демонстрируется работа особого вида конструктора для списка инициализации. Классы, содержащие подобные конструкторы, обрабатываются особым образом во время инициализации (см. ниже).

Класс std::initializer_list<> определён в стандартной библиотеке C++11. Однако, объекты данного класса могут быть созданы компилятором C++11 только статически с использованием синтаксиса со скобками {}. Список может быть скопирован после создания, однако, это будет копированием по ссылке. Список инициализации является константным: ни его члены, ни их данные не могут быть изменены после создания.

Так как std::initializer_list<> является полноценным типом, он может быть использован не только в конструкторах. Обычные функции могут получать типизированные списки инициализации в качестве аргумента, например:

void FunctionName(std::initializer_list<float> list);

FunctionName({1.0f, -3.45f, -0.4f});

Стандартные контейнеры могут быть инициализированы следующим образом:

std::vector<std::string> v = { "xyzzy", "plugh", "abracadabra" };
std::vector<std::string> v{ "xyzzy", "plugh", "abracadabra" };

Универсальная инициализация

В стандарте C++ содержится ряд проблем, связанных с инициализацией типов. Существует несколько путей инициализации типов и не все они приводят к одинаковым результатам. К примеру, традиционный синтаксис инициализирующего конструктора может выглядеть как описание функции, и нужно предпринять дополнительные меры, чтобы компилятор не ошибся при анализе. Только агрегирующие типы и POD типы могут быть инициализированы с помощью инициализаторов агрегатов (вида SomeType var = {/*stuff*/};).

C++11 предоставляет синтаксис, позволяющий использовать единую форму инициализации для всех видов объектов с помощью расширения синтаксиса списков инициализации:

struct BasicStruct {
    int x;
    double y;
};

struct AltStruct {
    AltStruct(int x, double y) : x_(x), y_(y) {}

private:
    int x_;
    double y_;
};

BasicStruct var1{5, 3.2};
AltStruct var2{2, 4.3};

Инициализация var1 работает точно так же, как и при инициализации агрегатов, то есть, каждый объект будет инициализирован копированием соответствующего значения из списка инициализации. При необходимости будет применено неявное преобразование типов. Если нужного преобразования не существует, исходный код будет считаться некорректным. Во время инициализации var2 будет вызван конструктор.

Предоставлена возможность писать подобный код:

struct IdString
{
    std::string name;
    int identifier;
};

IdString GetString()
{
    return {"SomeName", 4}; // Обратите внимание на отсутствие явного указания типов
}

Универсальная инициализация не заменяет полностью синтаксиса инициализации с помощью конструктора. Если в классе есть конструктор, принимающий в качестве аргумента список инициализации (ИмяТипа(initializer_list<SomeType>);), он будет иметь более высокий приоритет по сравнению с другими возможностями создания объектов. Например, в C++11 std::vector содержит конструктор, принимающий в качестве аргумента список инициализации:

std::vector<int> theVec{4};

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

Вывод типов

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

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

auto someStrangeCallableType = std::bind(&SomeFunction, _2, _1, someObject);
auto otherVariable = 5;

Типом someStrangeCallableType станет тот тип, который возвращает конкретная реализация шаблонной функции std::bind для заданных аргументов. Данный тип будет легко определён компилятором во время выполнения семантического анализа, а вот программисту для определения типа пришлось бы провести ряд изысканий.

Тип otherVariable также чётко определён, однако, так же легко может быть определён и программистом. Этот тип — int, такой же как у целочисленной константы.

Кроме того, для определения типа выражения во время компиляции может быть использовано ключевое слово decltype. Например:

int someInt;
decltype(someInt) otherIntegerVariable = 5;

Использование decltype наиболее полезно совместно с auto, так как тип переменной, описанной как auto<tt>, известен только компилятору. Кроме того, использование <tt>decltype может быть весьма полезным в выражениях, использующих перегрузку операторов и специализацию шаблонов.

auto также может быть использован для уменьшения избыточности кода. Например, вместо:

for (vector<int>::const_iterator itr = myvec.cbegin(); itr != myvec.cend(); ++itr)

программист сможет написать:

for (auto itr = myvec.cbegin(); itr != myvec.cend(); ++itr)

Разница становится особенно заметной, когда программист использует большое число различных контейнеров, несмотря на то, что и сейчас существует хороший путь для уменьшения избыточного кода — использование typedef.

Тип, помеченный как decltype, может отличаться от типа выведенного с помощью auto.

#include <vector>
int main()
{
  const std::vector<int> v(1);
  auto a = v[0];        // тип a - int  
  decltype(v[0]) b = 1; // тип b - const int& (возвращаемое значение
                        // std::vector<int>::operator[](size_type) const)
  auto c = 0;           // тип c - int   
  auto d = c;           // тип d - int            
  decltype(c) e;        // тип e - int, тип сущности, именованной как c 
  decltype((c)) f = c;  // тип f - int&, так как (c) является lvalue
  decltype(0) g;        // тип g - int, так как 0 является rvalue
}

For-цикл по коллекции

В стандартном C++ для перебора элементов коллекции требуется масса кода. В некоторых языках, например, в C#, есть средства, предоставляющие «foreach»-инструкцию, которая автоматически перебирает элементы коллекции от начала до конца. C++11 вводит подобное средство. Инструкция for позволит проще осуществлять перебор коллекции элементов:

int my_array[5] = {1, 2, 3, 4, 5};
for(int &x : my_array)
{
  x *= 2;
}

Эта форма for, называемая в английском языке «range-based for», посетит каждый элемент коллекции. Это будет применимо к C-массивам, спискам инициализаторов и любым другим типам, для которых определены функции begin() и end(), возвращающие итераторы. Все контейнеры стандартной библиотеки, имеющие пару begin/end, будут работать с for-инструкцией по коллекции.

Такой цикл будет работать и, например, с C-like массивами, т.к. C++11 вводит искусственно для них необходимые псевдометоды (begin, end и некоторые другие).

    // range-based обход классического массива
    int arr1[] = { 1, 2, 3 };
    for (auto el : arr1);

Лямбда-функции и выражения

В стандартном C++, например, при использовании алгоритмов стандартной библиотеки C++ sort и find, часто возникает потребность в определении функций-предикатов рядом с местом, где осуществляется вызов этого алгоритма. В языке существует только один механизм для этого: возможность определить класс функтора (передача экземпляра класса, определенного внутри функции, в алгоритмы запрещена (Meyers, Effective STL)). Зачастую данный способ является слишком избыточным и многословным и лишь затрудняет чтение кода. Кроме того, стандартные правила C++ для классов, определённых в функциях, не позволяют использовать их в шаблонах и таким образом делают их применение невозможным.

Очевидным решением проблемы явилось разрешение определения лямбда-выражений и лямбда-функций в C++11. Лямбда-функция определяется следующим образом:

[](int x, int y) { return x + y; }

Тип возвращаемого значения этой безымянной функции вычисляется как decltype(x+y). Тип возвращаемого значения может быть опущен только в том случае, если лямбда-функция представлена в форме return expression. Это ограничивает размер лямбда-функции до одного выражения.

Тип возвращаемого значения может быть указан явно, например:

[](int x, int y) -> int { int z = x + y; return z; }

В этом примере создаётся временная переменная z для хранения промежуточного значения. Как и в нормальных функциях, это промежуточное значение не сохраняется между вызовами.

Тип возвращаемого значения может быть полностью опущен, если функция не возвращает значения (то есть тип возвращаемого значения — void)

Также возможно использование ссылок на переменные, определённые в той же области видимости, что и лямбда-функция. Набор таких переменных обычно называют замыканием. Замыкания определяются и используются следующим образом:

std::vector<int> someList;
int total = 0;
std::for_each(someList.begin(), someList.end(), [&total](int x) {
  total += x;
});
std::cout << total;

Это отобразит сумму всех элементов в списке. Переменная total хранится как часть замыкания лямбда-функции. Так как она ссылается на стековую переменную total, она может менять её значение.

Переменные замыкания для локальных переменных могут быть также определены без использования символа ссылки &, что означает, что функция будет копировать значение. Это вынуждает пользователя заявлять о намерении сослаться на локальную переменную или скопировать её.

Для лямбда-функций, гарантированно исполняемых в области их видимости, возможно использование всех стековых переменных без необходимости явных ссылок на них:

std::vector<int> someList;
int total = 0;
std::for_each(someList.begin(), someList.end(), [&](int x) {
  total += x;
});

Способы внутренней реализации могут различаться, но предполагается, что лямбда-функция сохранит указатель на стек функции, в которой она создана, а не будет работать с отдельными ссылками на переменные стека.

Если вместо [&] используется [=], все используемые переменные будут скопированы, что позволяет использовать лямбда-функцию вне области действия исходных переменных.

Способ передачи по умолчанию можно также дополнить списком отдельных переменных. Например, если необходимо передать большинство переменных по ссылке, а одну по значению, можно использовать следующую конструкцию:

int total = 0;
int value = 5;
[&, value](int x) { total += (x * value); } (1); //(1) вызов лямбда-функции с передачей значения 1

Это вызовет передачу total по ссылке, а value — по значению.

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

[](SomeType *typePtr) { typePtr->SomePrivateMemberFunction(); }

Это будет работать только если областью создания лямбда-функции является метод класса SomeType.

Особым образом реализована работа с указателем this на объект, с которым взаимодействует текущий метод. Он должен быть явно обозначен в лямбда-функции:

[this]() { this->SomePrivateMemberFunction(); }

Использование формы [&] или [=] лямбда-функции делает this доступным автоматически.

Тип лямбда-функций зависит от реализации; имя этого типа доступно только компилятору. Если необходимо передать лямбда-функцию в качестве параметра, она должна быть шаблонного типа, либо сохранена с использованием std::function. Ключевое слово auto позволяет локально сохранить лямбда-функцию:

auto myLambdaFunc = [this]() { this->SomePrivateMemberFunction(); };

Кроме того, если функция не принимает аргументов, то () можно опустить:

auto myLambdaFunc = []{ std::cout << "hello" << std::endl; };

Альтернативный синтаксис функций

Иногда возникает потребность в реализации шаблона функции, результатом применения которого являлось бы выражение, имеющее тот же тип и ту же категорию значения (value category), что и у некоторого другого выражения.

template <typename LHS, typename RHS> 
    RETURN_TYPE AddingFunc(const LHS &lhs, const RHS &rhs) // каким должен быть RETURN_TYPE?
{
    return lhs + rhs;
}

Для того, чтобы выражение AddingFunc(x, y) имело тот же тип и ту же категорию значения, что и выражение lhs + rhs при передаче данных аргументов x и y, в рамках C++11 можно было бы использовать следующее определение:

template <typename LHS, typename RHS> 
    decltype(std::declval<const LHS &>() + std::declval<const RHS &>())
        AddingFunc(const LHS &lhs, const RHS &rhs)
{
    return lhs + rhs;
}

Данная запись несколько громоздка, и было бы хорошо иметь возможность вместо std::declval<const LHS &>() и std::declval<const RHS &>() использовать соответственно lhs и rhs. Однако в следующем варианте

template <typename LHS, typename RHS> 
    decltype(lhs + rhs) AddingFunc(const LHS &lhs, const RHS &rhs) // Не допустимо в C++11
{
    return lhs + rhs;
}

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

template <typename LHS, typename RHS> 
    auto AddingFunc(const LHS &lhs, const RHS &rhs) -> decltype(lhs + rhs)
{
    return lhs + rhs;
}

Следует отметить, однако, что в более обобщённой реализации AddingFunc, приведённой ниже, новый синтаксис не даёт выигрыша в плане краткости:

template <typename LHS, typename RHS> 
    auto AddingFunc(LHS &&lhs, RHS &&rhs) ->
        decltype(std::forward<LHS>(lhs) + std::forward<RHS>(rhs))
{
    return std::forward<LHS>(lhs) + std::forward<RHS>(rhs);
}
template <typename LHS, typename RHS> 
    auto AddingFunc(LHS &&lhs, RHS &&rhs) ->
        decltype(std::declval<LHS>() + std::declval<RHS>()) // эффект такой же, как и с std::forward выше
{
    return std::forward<LHS>(lhs) + std::forward<RHS>(rhs);
}
template <typename LHS, typename RHS> 
    decltype(std::declval<LHS>() + std::declval<RHS>()) // эффект такой же, как и с помещением типа в конец
        AddingFunc(LHS &&lhs, RHS &&rhs)
        
{
    return std::forward<LHS>(lhs) + std::forward<RHS>(rhs);
}

Новый синтаксис может использоваться в более простых объявлениях и описаниях:

struct SomeStruct
{
    auto FuncName(int x, int y) -> int;
};

auto SomeStruct::FuncName(int x, int y) -> int
{
    return x + y;
}

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

Улучшение конструкторов объектов

Стандартный C++ не допускает вызова одних конструкторов класса из других конструкторов этого же класса; каждый конструктор должен полностью инициализировать все члены класса либо вызывать для этого методы класса. Неконстантные члены класса не могут быть инициализированы в месте объявления этих членов.

C++11 избавляет от этих проблем.

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

Пример:

class SomeType  {
    int number;

public:
    SomeType(int new_number) : number(new_number) {}
    SomeType() : SomeType(42) {}
};

Из примера видно, что конструктор SomeType без аргументов вызывает конструктор того же класса с целочисленным аргументом для инициализации переменной number. Похожего эффекта можно было добиться, указав инициализирующее значение 42 для этой переменной прямо при её объявлении.

class SomeType  {
    int number = 42;

public:
    SomeType() {}
    explicit SomeType(int new_number) : number(new_number) {}
};

Любой конструктор класса будет инициализировать number значением 42, если он сам не присваивает ей другое значение.

Примером языков, которые так же решают эти проблемы служат Java, C# и D.

Следует заметить, что если в C++03 объект считается до конца созданным когда его конструктор завершает выполнение, то в C++11 после выполнения хотя бы одного делегирующего конструктора остальные конструкторы будут работать уже над полностью сконструированным объектом. Несмотря на это объекты производного класса начнут конструироваться только после выполнения всех конструкторов базовых классов.

Явное замещение виртуальных функций и финальность

Возможна ситуация, когда сигнатура виртуального метода изменена в базовом классе или изначально неправильно задана в производном классе. В таких случаях данный метод в классе-наследнике не будет замещать соответствующий метод базового класса. Так что если программист должным образом не изменит сигнатуру метода во всех классах-наследниках, метод может быть вызван некорректно в процессе выполнения программы. Например:

struct Base {
    virtual void some_func();
};

struct Derived : Base {
    void sone_func();
};

Здесь в имени виртуальной функции, объявленной в производном классе, допущена ошибка, поэтому такая функция не будет замещать Base::some_func и, соответственно, не будет вызываться полиморфно через указатель или ссылку на базовый подобъект.

В C++11 будет добавлена возможность отследить подобные проблемы на этапе компиляции (а не на этапе выполнения). Для обратной совместимости данная возможность является опциональной. Новый синтаксис представлен ниже:

struct B
{
    virtual void some_func();
    virtual void f(int);
    virtual void g() const;
};

struct D1 : public B
{
    void sone_func() override;          // ошибка: неверное имя функции
    void f(int) override;               // OK: замещает такую же функцию в базовом классе
    virtual void f(long) override;      // ошибка: несоответствие типа параметра
    virtual void f(int) const override; // ошибка: несоответствие cv-квалификации функции
    virtual int f(int) override;        // ошибка: несоответствие типа возврата
    virtual void g() const final;       // OK: замещает такую же функцию в базовом классе
    virtual void g(long);               // OK: новая виртуальная функция
};

struct D2 : D1
{
    virtual void g() const;             // ошибка: попытка замещения финальной функции
};

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

struct F final
{
    int x, y;
};

struct D : F  // ошибка: наследование от final классов запрещено
{
    int z;
};

Константа нулевого указателя

Со времён появления Си в 1972, константа 0 играла двойную роль целого числа и нулевого указателя. Одним из способов борьбы с этой неопределённостью, свойственной языку Си, служит макрос NULL, который обычно осуществляет подстановку ((void*)0) или 0. C++ в этом плане отличается от Си, позволяя использовать только 0 в качестве константы нулевого указателя. Это приводит к плохому взаимодействию с перегрузкой функций:

void foo(char *);
void foo(int);

Если макрос NULL определён как 0 (что является обычным для C++), строка foo(NULL); приведёт к вызову foo(int), а не foo(char *), как можно предположить при беглом просмотре кода, что почти наверняка не совпадает с планами программиста.

Одним из новшеств C++11 является новое ключевое слово для описания константы нулевого указателя — nullptr. Данная константа имеет тип std::nullptr_t, который можно неявно конвертировать в тип любого указателя и сравнить с любым указателем. Неявная конверсия в целочисленный тип недопустима, за исключением bool. В исходном предложении стандарта не допускалось неявной конверсии в булевый тип, но рабочая группа разработчиков стандарта разрешила такое преобразования в целях совместимости с обычными типами указателей. Предлагаемая формулировка была изменена после единогласного голосования в июне 2008[1].

В целях обеспечения обратной совместимости, константа 0 также может использоваться в качестве нулевого указателя.

char *pc = nullptr;     // верно
int  *pi = nullptr;     // верно
bool   b = nullptr;     // верно. b = false.
int    i = nullptr;     // ошибка

foo(nullptr);           // вызывает foo(char *), а не foo(int);

Перечисления со строгой типизацией

В стандартном C++ перечисления не являются типобезопасными. В действительности они представлены целыми числами, несмотря на то, что сами типы перечислений различны между собой. Это позволяет производить сравнения между двумя значениями из разных перечислений. Единственной возможностью, которую предлагает C++03 для защиты перечислений, является запрет на неявное преобразование целых чисел или элементов одного перечисления в элементы другого перечисления. Кроме того, способ представления в памяти (целочисленный тип) зависит от реализации и поэтому не является переносимым. Наконец, элементы перечислений имеют общую область видимости, что приводит к невозможности создания элементов с одинаковым именем в разных перечислениях.

C++11 предлагает специальную классификацию этих перечислений, свободную от вышеописанных недостатков. Для описания таких перечислений используется объявление enum class (также возможно использование enum struct в качестве синонима):

enum class Enumeration {
    Val1,
    Val2,
    Val3 = 100,
    Val4, /* = 101 */
};

Такое перечисление является типобезопасным. Элементы классового перечисления невозможно неявно преобразовать в целые числа. Как следствие, сравнение с целыми числами также невозможно (выражение Enumeration::Val4 == 101 приводит к ошибке компиляции).

Тип классового перечисления теперь не зависит от реализации. По умолчанию, как в случае выше, таким типом является int, но в иных случаях тип может быть задан вручную следующим образом:

enum class Enum2 : unsigned int {Val1, Val2};

Область действия элементов перечислений определяется областью действия имени перечисления. Использование имён элементов требует указания имени классового перечисления. Так, например, значение Enum2::Val1 определено, а значение Val1 — не определено.

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

enum Enum3 : unsigned long {Val1 = 1, Val2};

В данном примере имена элементов перечисления определены в пространстве перечисления (Enum3::Val1), но для обеспечения обратной совместимости имена элементов также доступны в общей области видимости.

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

enum Enum1;                   // неверно для C++ и C++11; низлежащий тип не может быть определён
enum Enum2 : unsigned int;    // верно для C++11, низлежащий тип указан явно
enum class Enum3;             // верно для C++11, низлежащий тип — int
enum class Enum4 : unsigned int; // верно для C++11.
enum Enum2 : unsigned short;  // неверно для C++11, поскольку Enum2 ранее объявлен с иным низлежащим типом

Угловые скобки

Парсеры стандартного C++ всегда определяют комбинацию символов «>>» как оператор правого сдвига. Отсутствие пробела между закрывающими угловыми скобками в параметрах шаблона (если они вложены) воспринимается как синтаксическая ошибка.

C++11 улучшает поведение анализатора в этом случае так, что несколько правых угловых скобок будут интерпретироваться как закрытие списков аргументов шаблонов.

Описанное поведение может быть исправлено в пользу старого подхода с помощью круглых скобок.

template<class T> class Y { /* ... */ };
Y<X<1>> x3;     // Правильно, то же, что и "Y<X<1> > x3;".
Y<X<6>>1>> x4;  // Синтаксическая ошибка. Нужно писать "Y<X<(6>>1)>> x4;".

Как было показано выше, данное изменение не совсем совместимо с предыдущим стандартом.

Операторы явного преобразования

Стандарт C++ предлагает ключевое слово explicit как модификатор конструкторов с одним параметром, чтобы такие конструкторы не функционировали как конструкторы неявного преобразования. Однако это никак не влияет на действительные операторы преобразования. Например, класс умного указателя может содержать operator bool() для имитации обычного указателя. Такой оператор можно вызвать, например, так: if(smart_ptr_variable) (ветка выполняется, если указатель ненулевой). Проблемой является то, что такой оператор не защищает от других непредвиденных преобразований. Поскольку в C++ тип bool объявлен как арифметический, возможно неявное преобразование в любой целочисленный тип или даже в тип числа с плавающей точкой, что в свою очередь может привести к непредвиденным математическим операциям.

В C++11 ключевое слово explicit применимо и к операторам преобразования. По аналогии с конструкторами, оно защищает от непредвиденных неявных преобразований. Однако ситуации, когда язык по контексту ожидает булевый тип (например, в условных выражениях, циклах и операндах логических операторов), считаются явными преобразованиями и оператор явного преобразования в bool вызывается непосредственно.

Шаблонный typedef

В стандартном C++ ключевое слово typedef можно использовать только как определение синонима для другого типа, в том числе, как синоним для спецификации шаблона с указанием всех его параметров. Но невозможно создание шаблонного синонима. Например:

template< typename First, typename Second, int third>
class SomeType;

template< typename Second>
typedef SomeType<OtherType, Second, 5> TypedefName; // Невозможно в C++

Это не будет компилироваться.

В C++11 добавлена эта возможность со следующим синтаксисом:

template< typename First, typename Second, int third>
class SomeType;

template< typename Second>
using TypedefName = SomeType<OtherType, Second, 5>;

В C++11 директива using также может использоваться для создания псевдонима типа данных.

typedef void (*OtherType)(double);	// Старый стиль
using OtherType = void (*)(double);	// Новый синтаксис

Снятие ограничений с union

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

Вот простой пример объединения, разрешённого в С++11:

//для placement new
#include <new>

struct Point  {
    Point() {}
    Point(int x, int y): x_(x), y_(y) {}
    int x_, y_;
};
union U {
    int z;
    double w;
    Point p;  // Неверно для C++03, поскольку Point имеет нетривиальный конструктор.  Однако код работает корректно в C++11.
    U() { new( &p ) Point(); } // Для объединения не определяются нетривиальные методы.
                               // При необходимости они могут быть удалены, чтобы работало ручное определение
};

Изменения не затрагивают существующий код, поскольку лишь ослабляют существующие ограничения.

Идентификаторы со специальным значением

Идентификаторы override и final имеют специальное значение только при использовании в определённых ситуациях. В остальных случаях они могут использоваться в качестве нормальных идентификаторов (например, как имя переменной или функции).

Расширение функциональности

В этом разделе описываются новые возможности, использование которых ранее было невозможным или требовало наличия специальных непереносимых библиотек.

Шаблоны с переменным числом аргументов

До появления C++11 шаблоны (классов или функций) могли принимать только заданное число аргументов, определяемых при первоначальном объявлении шаблона. C++11 позволяет определять шаблоны с переменным числом аргументов любого типа.

template<typename... Values> class tuple;

Шаблонный класс tuple (кортеж) принимает любое количество имён типов в качестве параметров шаблона:

class tuple<int, std::vector<int>, std::map<std::string, std::vector<int>>> some_instance_name;

Аргументы могут и отсутствовать, так что вариант class tuple<> some_instance_name также будет работать.

Чтобы инстанцирование шаблона без аргументов не происходило, можно использовать следующее определение:

template<typename First, typename... Rest> class tuple;

Шаблоны с переменным числом аргументов также применимы к функциям, что позволяет использовать их в типобезопасных вариантах функций с переменным числом аргументов (таких как printf), а также для обработки нетривиальных объектов.

template<typename... Params> void printf(const std::string &str_format, Params... parameters);

Оператор ... играет здесь две роли. Слева от Params оператор объявляет о необходимости упаковать параметры. Использование запакованных параметров позволяет связать 0 или более аргументов с шаблоном. Запакованные параметры могут использоваться не только для передачи имён типов. Оператор ... справа в свою очередь осуществляет распаковку параметров в отдельные аргументы (см. args... в теле функции в примере ниже).

Также возможно рекурсивное использование шаблонов с переменным числом аргументов. Одним из примеров может быть типобезопасная замена printf:

void printf(const char *s)
{
    while (*s) {
        if (*s == '%' && *(++s) != '%')
            throw std::runtime_error("invalid format string: missing arguments");
        std::cout << *s++;
    }
}

template<typename T, typename... Args>
void printf(const char *s, T value, Args... args)
{
    while (*s) {
        if (*s == '%' && *(++s) != '%') {
            std::cout << value;
            ++s;
            printf(s, args...); // продолжаем обработку аргументов, даже если *s == 0
            return;
        }
        std::cout << *s++;
    }
    throw std::logic_error("extra arguments provided to printf");
}

Этот шаблон является рекурсивным. Обратите внимание, что функция printf вызывает результаты инстанциирования самой себя или базовую функцию printf в случае, если args... пустой.

Нет простого механизма обхода параметров в шаблоне с переменным числом аргументов. Несмотря на это, использование оператора распаковки аргументов позволяет обойти эту проблему.

Например, класс может быть определён следующим образом:

template <typename... BaseClasses> class ClassName : public BaseClasses... {
public:

    ClassName (BaseClasses&&... base_classes) : BaseClasses(base_classes)... {}
};

Оператор распаковки продублирует все типы родительских классов ClassName таким образом, что класс будет наследован от всех типов, указанных в шаблонных параметрах. Кроме того, конструктор должен принимать ссылку на все базовые классы чтобы осуществлялась инициализация каждого базового класса-родителя ClassName.

Параметры шаблона могут быть перенаправлены. В сочетании с ссылками на rvalue (см. выше) можно выполнить перенаправление:

template<typename TypeToConstruct> struct SharedPtrAllocator {

    template<typename ...Args> std::shared_ptr<TypeToConstruct> construct_with_shared_ptr(Args&&... params) {
        return std::shared_ptr<TypeToConstruct>(new TypeToConstruct(std::forward<Args>(params)...));
    };
};

Данный код осуществляет распаковку списка аргументов в конструктор TypeToConstruct. Синтакс std::forward<Args>(params) позволяет абсолютно прозрачно перенаправить аргументы к конструктору, вне зависимости от их rvalue-характера. Функция автоматически оборачивает указатели в std::shared_ptr для обеспечения защиты от утечек памяти.

Также есть возможность определить число упакованных аргументов следующим образом:

template<typename ...Args> struct SomeStruct {
    static const int size = sizeof...(Args);
};

Здесь SomeStruct<Type1, Type2>::size равен 2, а SomeStruct<>::size равен 0.

Новые строковые литералы

C++03 предлагал два типа строковых литералов. Первый тип, строка, заключенная в двойные кавычки, представляет собой массив с завершающим нулем (null-terminated) типа const char. Второй тип, определенный как L"", представляет собой массив с завершающим нулем типа const wchar_t, где wchar_t является широким символом неопределенных размеров и семантики. Ни один из типов литералов не предполагает поддержку строковых литералов UTF-8, UTF-16, или любого другого типа Unicode кодировок.

Определение типа char было модифицировано до явного высказывания, что он по меньшей мере размера, необходимого для хранения восьми-битной кодировки UTF-8, и достаточно большой, чтобы содержать любой символ из набора символов времени выполнения. It was previously defined as only the latter in the C++ standard itself, then relying on the C standard to guarantee at least 8 bits.

Есть три Unicode кодировки, которые поддерживаются в стандарте C++11: UTF-8, UTF-16, и UTF-32. В дополнение к вышеуказанным изменениям встроенного символьного типа char, в C++11 добавлено два новых символьных типа: char16_t и char32_t. Они предназначены для хранения UTF-16 и UTF-32 символов соответственно.

Ниже показано, как создать строковые литералы для каждой из этих кодировок:

u8"I'm a UTF-8 string."
u"This is a UTF-16 string."
U"This is a UTF-32 string."

Типом первой строки является обычный const char[]. Тип второй строки — const char16_t[]. Тип третьей строки — const char32_t[].

При построении строковых литералов в стандарте Unicode, часто полезно вставить Unicode код прямо в строку. Для этого C++11 предлагает следующий синтаксис:

u8"This is a Unicode Character: \u2018."
u"This is a bigger Unicode Character: \u2018."
U"This is a Unicode Character: \U00002018."

Число после \u должно быть шестнадцатеричным; не нужно использовать префикс 0x. Идентификатор \u означает 16-битный Unicode код; для ввода 32-битного кода используется \U и 32-битное шестнадцатеричное число. Могут быть введены только действительные Unicode коды. Например, коды в диапазоне U+D800-U+DFFF запрещены, так как они зарезервированы для суррогатных пар в кодировке UTF-16.

Также иногда полезно избегать экранирования строк вручную, особенно при использовании литералов XML файлов, скриптовых языков программирования, или регулярных выражений. Для этих целей C++11 поддерживает «сырые» строковые литералы:

R"(The String Data \ Stuff " )"
R"delimiter(The String Data \ Stuff " )delimiter"

В первом случае всё между "( и )" является частью строки. Символы " и \ не нужно экранировать. Во втором случае "delimiter( начинает строку, и она заканчивается только при достижении )delimiter". Строка delimiter может быть любой строкой длиной до 16 символов, включая пустую строку. Эта строка не может содержать пробелы, управляющие символы, '(', ')', или символ '\'. Использование этой строки-разделителя позволяет использовать символ ')' в «сырых» строковых литералах. Например, R"delimiter((a-z))delimiter" эквивалентно "(a-z)".[3]

«Сырые» строковые литералы могут быть объединены с литералом из расширенного набора (префикс L"") или любыми префиксами Unicode литералов.

LR"(Raw wide string literal \t (without a tab))"
u8R"XXX(I'm a "raw UTF-8" string.)XXX"
uR"*(This is a "raw UTF-16" string.)*"
UR"(This is a "raw UTF-32" string.)"

Пользовательские литералы

Пользовательские литералы реализуются с помощью перегрузки оператора operator"". Литералы могут быть с квалификатором inline или constexpr. Желательно, чтобы литерал начинался с символа нижнего подчёркивания, так как может возникнуть коллизия с будущими стандартами. Например, литерал i уже принадлежит комплексным числам из std::complex.

Литералы могут принимать только один из следующих типов: const char * , unsigned long long int , long double , char , wchar_t , char16_t , char32_t. Достаточно перегрузить литерал только для типа const char *. Если не найдено более подходящего кандидата, то будет вызван оператор с этим типом. Пример преобразования миль в километры:

constexpr int operator "" _mi (unsigned long long int i)
{ return 1.6 * i;}

Строковые литералы принимают вторым аргументом std::size_t, а первым один из: const char * , const wchar_t *, const char16_t * , const char32_t *. Строковые литералы применяются к записям, записанным в двойных кавычках.

Многопоточная модель памяти

Внутрипоточное хранилище

Явное задание по умолчанию и удаление специальных методов

Тип long long int

Целый тип long long int специфицирован в C99 и де-факто широко применяется в C++. Теперь его официально включили в стандарт.

Статическая диагностика

C++11 имеет два механизма статической диагностики:

  • Ключевое слово static_assert выдаёт ошибку компиляции, если выражение в скобках ложно.
  • Библиотека type_traits, содержащая шаблоны, выдающие информацию о типе прямо во время компиляции.
#include <type_traits>

template<class T>
void run(T *aData, size_t n)
{
   static_assert(std::is_pod<T>::value, "Тип T должен быть простым.");
   ...
}

Работа sizeof с элементами данных в классах без создания объекта

C++03 позволял использовать оператор sizeof для простых типов и объектов. Но следующая конструкция была недопустима:

struct SomeType { OtherType member; };

sizeof(SomeType::member); //Не работает в C++03, но верно для C++11.

Результатом этого вызова должен быть размер OtherType. C++03 не поддерживает такой вызов и данный код не будет скомпилирован. C++11 разрешает подобные конструкции.

Управление выравниванием объектов и запросы на выравнивание

C++11 позволяет выравнивать переменный с помощью операторовalignof и alignas.

alignof принимает тип и возвращает число байт, на которые можно смещать объект. Например для struct X { int n; char c; };, размер которой равен 8 байтам, alignof вернёт значение 4. Для ссылок он возвращает значение для типа ссылки; для масивов — значение для элемента массива

alignas управляет выравниванием объекта в памяти. Например, можно указать, чтобы массив char должен был быть выравнен соответствующим образом, чтобы хранить тип float:

alignas(float) unsigned char c[sizeof(float)]

Разрешение реализаций со сборщиком мусора

Атрибуты

Изменения стандартной библиотеки C++

Изменения в имеющихся компонентах

  • При массовой вставке в std::set программист зачастую знает, куда[что?] вставлять. Для этого служит необязательный параметр — «хинт»; его смысл изменили. Раньше он означал элемент до текущего, что не совсем правильно: непонятно, что делать, если вставка в первую позицию. Теперь это элемент после текущего.
  • Написан удобный шаблон, вызывающий конструкторы без выделения памяти — std::allocator_traits<>::construct(). Во все контейнеры добавили метод emplace, создающий объект на месте.
  • Добавлены новые языковые возможности C++11.
  • Добавлены методы cbegin и cend, гарантированно создающие константные итераторы. Удобно для метапрограммирования, для задания типов через auto.
  • В контейнерах, которые заводят память с запасом, появилась функция shrink_to_fit.
  • В std::list поставлены более жёсткие рамки на то, что выполняется за O(n), а что — за константное время.
  • В std::vector добавился прямой доступ к памяти через data().
  • Запретили нескольким std::string ссылаться на одну и ту же память. Благодаря этому появился и прямой доступ через front(), удобный, например, для взаимодействия string’а и WinAPI.


Хеш-таблицы

std::hash_set и std::hash_map давно были нестандартным расширением STL, по факту реализованным в большинстве компиляторов. В C++11 они стали стандартом, под именами std::unordered_set и std::unordered_map. Хотя по факту это хеш-таблицы и стандарт не оставляет много пространства для манёвра, имена даны в стиле C++: не «как они реализованы», а «что они собой представляют».

Регулярные выражения

Новая библиотека, объявленная в заголовочном файле <regex>, содержит в себе несколько новых классов:

  • Регулярные выражения представлены в виде экземпляров класса std::regex;
  • результаты поиска представлены в виде экземпляров шаблона std::match_results.

Функция std::regex_search используется для поиска, для операции ‘найти и заменить’ используется функция std::regex_replace. Функция вернет строку после выполнения замены. Алгоритмы std::regex_search и std::regex_replace получают на вход регулярное выражение и строку и возвращают найденные результаты в виде экземпляра std::match_results.

Пример использования std::match_results:

const char *reg_esp = "[ ,.\\t\\n;:]";  // Список символов-разделителей.

// то же самое можно сделать, используя "сырые" строки:
// const char *reg_esp = R"([ ,.\t\n;:])";

std::regex rgx(reg_esp);  // 'regex' - это экземпляр шаблонного класса
                      // 'basic_regex' с шаблонным параметром 'char'.
std::cmatch match;  // 'cmatch' - это экземпляр шаблонного класса
                // 'match_results' с шаблонным параметром 'const char *'.
const char *target = "Unseen University - Ankh-Morpork";

// Фиксирует все слова строки 'target' разделенные символами из 'reg_esp'.
if( std::regex_search( target, match, rgx ) ) {
    // Если слова, разделенные заданными символами присутствуют в строке.

    const size_t n = match.size();
    for( size_t a = 0; a < n; a++ ) {
        std::string str( match[a].first, match[a].second );
        std::cout << str << "\n";
    }
}

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

Библиотека <regex> не требует ни изменения существующих заголовочных файлов, ни установки дополнительных расширений языка.


Расширяемые классы генерации случайных чисел

Стандартная библиотека Си позволяла генерировать псевдо-случайные числа с помощью функции rand. Однако её поведение могло варьироваться в зависимости от реализации.

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

Движки генераторов:

Распределения:

Пример:

#include <random>
#include <functional>

std::uniform_int_distribution<int> distribution(0, 99);
std::mt19937 engine; // Вихрь Мерсенна MT19937
auto generator = std::bind(distribution, engine);
int random = generator(); // Получить случайное число от 0 до 99.
int random2 = distribution(engine); // Получить случайное число, используя движок и распределение напрямую.



Запланированные возможности, не вошедшие в стандарт

Модули 
Огромный объём заголовочных файлов привёл к квадратичному повышению времени компиляции: увеличивается и объём кода, и количество модулей в отдельно взятой единице компиляции. Модули должны дать механизм, напоминающий DCU-файлы Delphi или class-файлы Java.


Удалённые или устаревшие возможности

См. также

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

Примечания

  1. Herb Sutter, [herbsutter.com/2011/08/12/we-have-an-international-standard-c0x-is-unanimously-approved/ We have an international standard: C++0x is unanimously approved]
  2. Scott Meyers, [www.aristeia.com/C++0x/C++0xFeatureAvailability.htm Summary of C++11 Feature Availability in gcc and MSVC], 16 August 2011
  3. ISO, [www.iso.org/iso/iso_catalogue/catalogue_tc/catalogue_detail.htm?csnumber=50372 ISO/IEC 14882:2011]
  4. Название С++0x определено в финальном черновике [www.open-std.org/jtc1/sc22/open/n3290.html N3290]
  5. Страуструп, Бьорн — [www2.research.att.com/~bs/C++0xFAQ.html C++0x — the next ISO C++ standard]
  6. [herbsutter.com/2011/08/12/we-have-an-international-standard-c0x-is-unanimously-approved/ We have an international standard: C++0x is unanimously approved by Herb Sutter]
  7. [www.open-std.org/jtc1/sc22/wg21/docs/papers/ C++ Standards Committee Papers]
  8. 1 2 The C++ Source Bjarne Stroustrup (January 2, 2006) A Brief Look at C++0x(англ.)

Документы комитета по стандартизации C++

  •   Doc No. [www.open-std.org/jtc1/sc22/wg21/docs/papers/2002/n1401.pdf 1401]: Jan Kristoffersen (October 21, 2002) Atomic operations with multi-threaded environments
  •   Doc No. [www.open-std.org/jtc1/sc22/wg21/docs/papers/2002/n1402.html 1402]: Doug Gregor (October 22, 2002) A Proposal to add a Polymorphic Function Object Wrapper to the Standard Library
  •   Doc No. [www.open-std.org/jtc1/sc22/wg21/docs/papers/2002/n1403.pdf 1403]: Doug Gregor (November 8, 2002) Proposal for adding tuple types into the standard library
  •   Doc No. [www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1424.htm 1424]: John Maddock (March 3, 2003) A Proposal to add Type Traits to the Standard Library
  •   Doc No. [www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1429.htm 1429]: John Maddock (March 3, 2003) A Proposal to add Regular Expression to the Standard Library
  •   Doc No. [www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1449.pdf 1449]: B. Stroustrup, G. Dos Reis, Mat Marcus, Walter E. Brown, Herb Sutter (April 7, 2003) Proposal to add template aliases to C++
  •   Doc No. [www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1450.html 1450]: P. Dimov, B. Dawes, G. Colvin (March 27, 2003) A Proposal to Add General Purpose Smart Pointers to the Library Technical Report (Revision 1)
  •   Doc No. [www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1452.html 1452]: Jens Maurer (April 10, 2003) A Proposal to Add an Extensible Random Number Facility to the Standard Library (Revision 2)
  •   Doc No. [www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1453.html 1453]: D. Gregor, P. Dimov (April 9, 2003) A proposal to add a reference wrapper to the standard library (revision 1)
  •   Doc No. [www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1454.html 1454]: Douglas Gregor, P. Dimov (April 9, 2003) A uniform method for computing function object return types (revision 1)
  •   Doc No. [www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1456.html 1456]: Matthew Austern (April 9, 2003) A Proposal to Add Hash Tables to the Standard Library (revision 4)
  •   Doc No. [www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1471.pdf 1471]: Daveed Vandevoorde (April 18, 2003) Reflective Metaprogramming in C++
  •   Doc No. [www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1676.htm 1676]: Bronek Kozicki (September 9, 2004) Non-member overloaded copy assignment operator
  •   Doc No. [www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1704.pdf 1704]: Douglas Gregor, Jaakko Järvi, Gary Powell (September 10, 2004) Variadic Templates: Exploring the Design Space
  •   Doc No. [www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1705.pdf 1705]: J. Järvi, B. Stroustrup, D. Gregor, J. Siek, G. Dos Reis (September 12, 2004) Decltype (and auto)
  •   Doc No. [www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1717.pdf 1717]: Francis Glassborow, Lois Goldthwaite (November 5, 2004) explicit class and default definitions
  •   Doc No. [www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1719.pdf 1719]: Herb Sutter, David E. Miller (October 21, 2004) Strongly Typed Enums (revision 1)
  •   Doc No. [www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1720.html 1720]: R. Klarer, J. Maddock, B. Dawes, H. Hinnant (October 20, 2004) Proposal to Add Static Assertions to the Core Language (Revision 3)
  •   Doc No. [www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1757.html 1757]: Daveed Vandevoorde (January 14, 2005) Right Angle Brackets (Revision 2)
  •   Doc No. [www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1811.pdf 1811]: J. Stephen Adamczyk (April 29, 2005) Adding the long long type to C++ (Revision 3)
  •   Doc No. [www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1815.html 1815]: Lawrence Crowl (May 2, 2005) ISO C++ Strategic Plan for Multithreading
  •   Doc No. [www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1827.htm 1827]: Chris Uzdavinis, Alisdair Meredith (August 29, 2005) An Explicit Override Syntax for C++
  •   Doc No. [www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1834.html 1834]: Detlef Vollmann (June 24, 2005) A Pleading for Reasonable Parallel Processing Support in C++
  •   Doc No. [www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1836.pdf 1836]: ISO/IEC DTR 19768 (June 24, 2005) Draft Technical Report on C++ Library Extensions
  •   Doc No. [www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1886.pdf 1886]: Gabriel Dos Reis, Bjarne Stroustrup (October 20, 2005) Specifying C++ concepts
  •   Doc No. [www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1891.pdf 1891]: Walter E. Brown (October 18, 2005) Progress toward Opaque Typedefs for C++0X
  •   Doc No. [www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1898.pdf 1898]: Michel Michaud, Michael Wong (October 6, 2004) Forwarding and inherited constructors
  •   Doc No. [www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1919.pdf 1919]: Bjarne Stroustrup, Gabriel Dos Reis (December 11, 2005) Initializer lists
  •   Doc No. [www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1968.pdf 1968]: V Samko; J Willcock, J Järvi, D Gregor, A Lumsdaine (February 26, 2006) Lambda expressions and closures for C++
  •   Doc No. [www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1986.pdf 1986]: Herb Sutter, Francis Glassborow (April 6, 2006) Delegating Constructors (revision 3)
  •   Doc No. [www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2016.html 2016]: Hans Boehm, Nick Maclaren (April 21, 2002) Should volatile Acquire Atomicity and Thread Visibility Semantics?
  •   Doc No. [www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2142.html 2142]: ISO/IEC DTR 19768 (January 12, 2007) State of C++ Evolution (between Portland and Oxford 2007 Meetings)
  •   Doc No. [www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2228.html 2228]: ISO/IEC DTR 19768 (May 3, 2007) State of C++ Evolution (Oxford 2007 Meetings)
  •   Doc No. [www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2258.pdf 2258]: G. Dos Reis and B. Stroustrup Templates Aliases
  •   Doc No. [www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2280.html 2280]: Lawrence Crowl (May 2, 2007) Thread-Local Storage
  •   Doc No. [www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2291.html 2291]: ISO/IEC DTR 19768 (June 25, 2007) State of C++ Evolution (Toronto 2007 Meetings)
  •   Doc No. [www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2336.html 2336]: ISO/IEC DTR 19768 (July 29, 2007) State of C++ Evolution (Toronto 2007 Meetings)
  •   Doc No. [www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2389.html 2389]: ISO/IEC DTR 19768 (August 7, 2007) State of C++ Evolution (pre-Kona 2007 Meetings)
  •   Doc No. [www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2431.pdf 2431]: SC22/WG21/N2431 = J16/07-0301 (October 2, 2007), A name for the null pointer: nullptr
  •   Doc No. [www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2432.html 2432]: ISO/IEC DTR 19768 (October 23, 2007) State of C++ Evolution (post-Kona 2007 Meeting)
  •   Doc No. [www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2437.pdf 2437]: Lois Goldthwaite (October 5, 2007) Explicit Conversion Operators
  •   Doc No. [www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2461.pdf 2461]: ISO/IEC DTR 19768 (October 22, 2007) Working Draft, Standard for programming Language C++
  •   Doc No. [www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2507.html 2507]: ISO/IEC DTR 19768 (February 4, 2008) State of C++ Evolution (pre-Bellevue 2008 Meeting)
  •   Doc No. [www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2544.pdf 2544]: Alan Talbot, Lois Goldthwaite, Lawrence Crowl, Jens Maurer (February 29, 2008) Unrestricted unions
  •   Doc No. [www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2565.html 2565]: ISO/IEC DTR 19768 (March 7, 2008) State of C++ Evolution (post-Bellevue 2008 Meeting)
  •   Doc No. [www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2597.html 2597]: ISO/IEC DTR 19768 (April 29, 2008) State of C++ Evolution (pre-Antipolis 2008 Meeting)
  •   Doc No. [www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2606.pdf 2606]: ISO/IEC DTR 19768 (May 19, 2008) Working Draft, Standard for Programming Language C++
  •   Doc No. [www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2697.html 2697]: ISO/IEC DTR 19768 (June 15, 2008) Minutes of WG21 Meeting June 8-15, 2008
  •   Doc No. [www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2798.pdf 2798]: ISO/IEC DTR 19768 (October 4, 2008) Working Draft, Standard for Programming Language C++
  •   Doc No. [www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2857.pdf 2857]: ISO/IEC DTR 19768 (March 23, 2009) Working Draft, Standard for Programming Language C++
  •   Doc No. [www.open-std.org/JTC1/SC22/WG21/docs/papers/2009/n2869.html 2869]: ISO/IEC DTR 19768 (April 28, 2009) State of C++ Evolution (post-San Francisco 2008 Meeting)
  •   Doc No. [www.open-std.org/JTC1/SC22/WG21/docs/papers/2009/n3000.pdf 3000]: ISO/ISC DTR 19769 (November 9, 2009) Working Draft, Standard for Programming Language C++
  •   Doc No. [www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n3014.pdf 3014]: Stephen D. Clamage (November 4, 2009) AGENDA, PL22.16 Meeting No. 53, WG21 Meeting No. 48, March 8-13, 2010, Pittsburgh, PA
  •   Doc No. [www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3082.pdf 3082]: Herb Sutter (March 13, 2010) C++0x Meeting Schedule
  •   Doc No. [www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3092.pdf 3092]: ISO/ISC DTR 19769 (March 26, 2010) Working Draft, Standard for Programming Language C++
  •   Doc No. [www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3126.pdf 3126]: ISO/ISC DTR 19769 (August 21, 2010) Working Draft, Standard for Programming Language C++
  •   Doc No. [www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3225.pdf 3225]: ISO/ISC DTR 19769 (November 27, 2010) Working Draft, Standard for Programming Language C++
  •   Doc No. [www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3242.pdf 3242]: ISO/ISC DTR 19769 (February 28, 2011) Working Draft, Standard for Programming Language C++
  •   Doc No. 3291: ISO/ISC DTR 19769 (April 5, 2011) Working Draft, Standard for Programming Language C++
  •   Doc No. 3290: ISO/ISC DTR 19769 (April 5, 2011) FDIS, Standard for Programming Language C++
  •   Doc No. [www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3337.pdf 3337]: Date: 2012-01-16 Working Draft, Standard for Programming Language C++

Ссылки

  • Бьёрн Страуструп. [www2.research.att.com/~bs/C++0xFAQ.html C++0x - the next ISO C++ standard]. AT&T (11 January 2010). Проверено 26 августа 2011. [www.webcitation.org/67lm9jiEq Архивировано из первоисточника 19 мая 2012].
  • [wiki.apache.org/stdcxx/C++0xCompilerSupport Поддержка C++0x различными компиляторами]. [www.webcitation.org/67lmA9rma Архивировано из первоисточника 19 мая 2012].
  • [habrahabr.ru/post/207894/ Интервью с Бьерном Страуструпом о языке C++]. - [electronicdesign.com/dev-tools/interview-bjarne-stroustrup-discusses-c оригинал на англ.] // ElectronicDesign.com, Oct. 29, 2013

Литература

  • Стенли Б. Липпман, Жози Лажойе, Барбара Э. Му. Язык программирования C++. Базовый курс, 5-е издание = C++ Primer (5th Edition). — М.: «Вильямс», 2014. — 1120 с. — ISBN 978-5-8459-1839-0.
  • Сиддхартха Рао. Освой самостоятельно C++ за 21 день, 7-е издание = Sams Teach Yourself C++ in One Hour a Day, 7th Edition. — М.: «Вильямс», 2013. — 688 с. — ISBN 978-5-8459-1825-3.
  • Стивен Прата. Язык программирования C++ (C++11). Лекции и упражнения, 6-е издание = C++ Primer Plus, 6th Edition (Developer's Library). — М.: «Вильямс», 2012. — 1248 с. — ISBN 978-5-8459-1778-2.


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


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


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


На другой день простившись только с одним графом, не дождавшись выхода дам, князь Андрей поехал домой.
Уже было начало июня, когда князь Андрей, возвращаясь домой, въехал опять в ту березовую рощу, в которой этот старый, корявый дуб так странно и памятно поразил его. Бубенчики еще глуше звенели в лесу, чем полтора месяца тому назад; всё было полно, тенисто и густо; и молодые ели, рассыпанные по лесу, не нарушали общей красоты и, подделываясь под общий характер, нежно зеленели пушистыми молодыми побегами.
Целый день был жаркий, где то собиралась гроза, но только небольшая тучка брызнула на пыль дороги и на сочные листья. Левая сторона леса была темна, в тени; правая мокрая, глянцовитая блестела на солнце, чуть колыхаясь от ветра. Всё было в цвету; соловьи трещали и перекатывались то близко, то далеко.
«Да, здесь, в этом лесу был этот дуб, с которым мы были согласны», подумал князь Андрей. «Да где он», подумал опять князь Андрей, глядя на левую сторону дороги и сам того не зная, не узнавая его, любовался тем дубом, которого он искал. Старый дуб, весь преображенный, раскинувшись шатром сочной, темной зелени, млел, чуть колыхаясь в лучах вечернего солнца. Ни корявых пальцев, ни болячек, ни старого недоверия и горя, – ничего не было видно. Сквозь жесткую, столетнюю кору пробились без сучков сочные, молодые листья, так что верить нельзя было, что этот старик произвел их. «Да, это тот самый дуб», подумал князь Андрей, и на него вдруг нашло беспричинное, весеннее чувство радости и обновления. Все лучшие минуты его жизни вдруг в одно и то же время вспомнились ему. И Аустерлиц с высоким небом, и мертвое, укоризненное лицо жены, и Пьер на пароме, и девочка, взволнованная красотою ночи, и эта ночь, и луна, – и всё это вдруг вспомнилось ему.
«Нет, жизнь не кончена в 31 год, вдруг окончательно, беспеременно решил князь Андрей. Мало того, что я знаю всё то, что есть во мне, надо, чтобы и все знали это: и Пьер, и эта девочка, которая хотела улететь в небо, надо, чтобы все знали меня, чтобы не для одного меня шла моя жизнь, чтоб не жили они так независимо от моей жизни, чтоб на всех она отражалась и чтобы все они жили со мною вместе!»

Возвратившись из своей поездки, князь Андрей решился осенью ехать в Петербург и придумал разные причины этого решенья. Целый ряд разумных, логических доводов, почему ему необходимо ехать в Петербург и даже служить, ежеминутно был готов к его услугам. Он даже теперь не понимал, как мог он когда нибудь сомневаться в необходимости принять деятельное участие в жизни, точно так же как месяц тому назад он не понимал, как могла бы ему притти мысль уехать из деревни. Ему казалось ясно, что все его опыты жизни должны были пропасть даром и быть бессмыслицей, ежели бы он не приложил их к делу и не принял опять деятельного участия в жизни. Он даже не понимал того, как на основании таких же бедных разумных доводов прежде очевидно было, что он бы унизился, ежели бы теперь после своих уроков жизни опять бы поверил в возможность приносить пользу и в возможность счастия и любви. Теперь разум подсказывал совсем другое. После этой поездки князь Андрей стал скучать в деревне, прежние занятия не интересовали его, и часто, сидя один в своем кабинете, он вставал, подходил к зеркалу и долго смотрел на свое лицо. Потом он отворачивался и смотрел на портрет покойницы Лизы, которая с взбитыми a la grecque [по гречески] буклями нежно и весело смотрела на него из золотой рамки. Она уже не говорила мужу прежних страшных слов, она просто и весело с любопытством смотрела на него. И князь Андрей, заложив назад руки, долго ходил по комнате, то хмурясь, то улыбаясь, передумывая те неразумные, невыразимые словом, тайные как преступление мысли, связанные с Пьером, с славой, с девушкой на окне, с дубом, с женской красотой и любовью, которые изменили всю его жизнь. И в эти то минуты, когда кто входил к нему, он бывал особенно сух, строго решителен и в особенности неприятно логичен.
– Mon cher, [Дорогой мой,] – бывало скажет входя в такую минуту княжна Марья, – Николушке нельзя нынче гулять: очень холодно.
– Ежели бы было тепло, – в такие минуты особенно сухо отвечал князь Андрей своей сестре, – то он бы пошел в одной рубашке, а так как холодно, надо надеть на него теплую одежду, которая для этого и выдумана. Вот что следует из того, что холодно, а не то чтобы оставаться дома, когда ребенку нужен воздух, – говорил он с особенной логичностью, как бы наказывая кого то за всю эту тайную, нелогичную, происходившую в нем, внутреннюю работу. Княжна Марья думала в этих случаях о том, как сушит мужчин эта умственная работа.


Князь Андрей приехал в Петербург в августе 1809 года. Это было время апогея славы молодого Сперанского и энергии совершаемых им переворотов. В этом самом августе, государь, ехав в коляске, был вывален, повредил себе ногу, и оставался в Петергофе три недели, видаясь ежедневно и исключительно со Сперанским. В это время готовились не только два столь знаменитые и встревожившие общество указа об уничтожении придворных чинов и об экзаменах на чины коллежских асессоров и статских советников, но и целая государственная конституция, долженствовавшая изменить существующий судебный, административный и финансовый порядок управления России от государственного совета до волостного правления. Теперь осуществлялись и воплощались те неясные, либеральные мечтания, с которыми вступил на престол император Александр, и которые он стремился осуществить с помощью своих помощников Чарторижского, Новосильцева, Кочубея и Строгонова, которых он сам шутя называл comite du salut publique. [комитет общественного спасения.]
Теперь всех вместе заменил Сперанский по гражданской части и Аракчеев по военной. Князь Андрей вскоре после приезда своего, как камергер, явился ко двору и на выход. Государь два раза, встретив его, не удостоил его ни одним словом. Князю Андрею всегда еще прежде казалось, что он антипатичен государю, что государю неприятно его лицо и всё существо его. В сухом, отдаляющем взгляде, которым посмотрел на него государь, князь Андрей еще более чем прежде нашел подтверждение этому предположению. Придворные объяснили князю Андрею невнимание к нему государя тем, что Его Величество был недоволен тем, что Болконский не служил с 1805 года.
«Я сам знаю, как мы не властны в своих симпатиях и антипатиях, думал князь Андрей, и потому нечего думать о том, чтобы представить лично мою записку о военном уставе государю, но дело будет говорить само за себя». Он передал о своей записке старому фельдмаршалу, другу отца. Фельдмаршал, назначив ему час, ласково принял его и обещался доложить государю. Через несколько дней было объявлено князю Андрею, что он имеет явиться к военному министру, графу Аракчееву.
В девять часов утра, в назначенный день, князь Андрей явился в приемную к графу Аракчееву.
Лично князь Андрей не знал Аракчеева и никогда не видал его, но всё, что он знал о нем, мало внушало ему уважения к этому человеку.
«Он – военный министр, доверенное лицо государя императора; никому не должно быть дела до его личных свойств; ему поручено рассмотреть мою записку, следовательно он один и может дать ход ей», думал князь Андрей, дожидаясь в числе многих важных и неважных лиц в приемной графа Аракчеева.
Князь Андрей во время своей, большей частью адъютантской, службы много видел приемных важных лиц и различные характеры этих приемных были для него очень ясны. У графа Аракчеева был совершенно особенный характер приемной. На неважных лицах, ожидающих очереди аудиенции в приемной графа Аракчеева, написано было чувство пристыженности и покорности; на более чиновных лицах выражалось одно общее чувство неловкости, скрытое под личиной развязности и насмешки над собою, над своим положением и над ожидаемым лицом. Иные задумчиво ходили взад и вперед, иные шепчась смеялись, и князь Андрей слышал sobriquet [насмешливое прозвище] Силы Андреича и слова: «дядя задаст», относившиеся к графу Аракчееву. Один генерал (важное лицо) видимо оскорбленный тем, что должен был так долго ждать, сидел перекладывая ноги и презрительно сам с собой улыбаясь.
Но как только растворялась дверь, на всех лицах выражалось мгновенно только одно – страх. Князь Андрей попросил дежурного другой раз доложить о себе, но на него посмотрели с насмешкой и сказали, что его черед придет в свое время. После нескольких лиц, введенных и выведенных адъютантом из кабинета министра, в страшную дверь был впущен офицер, поразивший князя Андрея своим униженным и испуганным видом. Аудиенция офицера продолжалась долго. Вдруг послышались из за двери раскаты неприятного голоса, и бледный офицер, с трясущимися губами, вышел оттуда, и схватив себя за голову, прошел через приемную.
Вслед за тем князь Андрей был подведен к двери, и дежурный шопотом сказал: «направо, к окну».
Князь Андрей вошел в небогатый опрятный кабинет и у стола увидал cорокалетнего человека с длинной талией, с длинной, коротко обстриженной головой и толстыми морщинами, с нахмуренными бровями над каре зелеными тупыми глазами и висячим красным носом. Аракчеев поворотил к нему голову, не глядя на него.
– Вы чего просите? – спросил Аракчеев.
– Я ничего не… прошу, ваше сиятельство, – тихо проговорил князь Андрей. Глаза Аракчеева обратились на него.
– Садитесь, – сказал Аракчеев, – князь Болконский?
– Я ничего не прошу, а государь император изволил переслать к вашему сиятельству поданную мною записку…
– Изволите видеть, мой любезнейший, записку я вашу читал, – перебил Аракчеев, только первые слова сказав ласково, опять не глядя ему в лицо и впадая всё более и более в ворчливо презрительный тон. – Новые законы военные предлагаете? Законов много, исполнять некому старых. Нынче все законы пишут, писать легче, чем делать.
– Я приехал по воле государя императора узнать у вашего сиятельства, какой ход вы полагаете дать поданной записке? – сказал учтиво князь Андрей.
– На записку вашу мной положена резолюция и переслана в комитет. Я не одобряю, – сказал Аракчеев, вставая и доставая с письменного стола бумагу. – Вот! – он подал князю Андрею.
На бумаге поперег ее, карандашом, без заглавных букв, без орфографии, без знаков препинания, было написано: «неосновательно составлено понеже как подражание списано с французского военного устава и от воинского артикула без нужды отступающего».
– В какой же комитет передана записка? – спросил князь Андрей.
– В комитет о воинском уставе, и мною представлено о зачислении вашего благородия в члены. Только без жалованья.
Князь Андрей улыбнулся.
– Я и не желаю.
– Без жалованья членом, – повторил Аракчеев. – Имею честь. Эй, зови! Кто еще? – крикнул он, кланяясь князю Андрею.


Ожидая уведомления о зачислении его в члены комитета, князь Андрей возобновил старые знакомства особенно с теми лицами, которые, он знал, были в силе и могли быть нужны ему. Он испытывал теперь в Петербурге чувство, подобное тому, какое он испытывал накануне сражения, когда его томило беспокойное любопытство и непреодолимо тянуло в высшие сферы, туда, где готовилось будущее, от которого зависели судьбы миллионов. Он чувствовал по озлоблению стариков, по любопытству непосвященных, по сдержанности посвященных, по торопливости, озабоченности всех, по бесчисленному количеству комитетов, комиссий, о существовании которых он вновь узнавал каждый день, что теперь, в 1809 м году, готовилось здесь, в Петербурге, какое то огромное гражданское сражение, которого главнокомандующим было неизвестное ему, таинственное и представлявшееся ему гениальным, лицо – Сперанский. И самое ему смутно известное дело преобразования, и Сперанский – главный деятель, начинали так страстно интересовать его, что дело воинского устава очень скоро стало переходить в сознании его на второстепенное место.
Князь Андрей находился в одном из самых выгодных положений для того, чтобы быть хорошо принятым во все самые разнообразные и высшие круги тогдашнего петербургского общества. Партия преобразователей радушно принимала и заманивала его, во первых потому, что он имел репутацию ума и большой начитанности, во вторых потому, что он своим отпущением крестьян на волю сделал уже себе репутацию либерала. Партия стариков недовольных, прямо как к сыну своего отца, обращалась к нему за сочувствием, осуждая преобразования. Женское общество, свет , радушно принимали его, потому что он был жених, богатый и знатный, и почти новое лицо с ореолом романической истории о его мнимой смерти и трагической кончине жены. Кроме того, общий голос о нем всех, которые знали его прежде, был тот, что он много переменился к лучшему в эти пять лет, смягчился и возмужал, что не было в нем прежнего притворства, гордости и насмешливости, и было то спокойствие, которое приобретается годами. О нем заговорили, им интересовались и все желали его видеть.
На другой день после посещения графа Аракчеева князь Андрей был вечером у графа Кочубея. Он рассказал графу свое свидание с Силой Андреичем (Кочубей так называл Аракчеева с той же неопределенной над чем то насмешкой, которую заметил князь Андрей в приемной военного министра).
– Mon cher, [Дорогой мой,] даже в этом деле вы не минуете Михаил Михайловича. C'est le grand faiseur. [Всё делается им.] Я скажу ему. Он обещался приехать вечером…
– Какое же дело Сперанскому до военных уставов? – спросил князь Андрей.
Кочубей, улыбнувшись, покачал головой, как бы удивляясь наивности Болконского.
– Мы с ним говорили про вас на днях, – продолжал Кочубей, – о ваших вольных хлебопашцах…
– Да, это вы, князь, отпустили своих мужиков? – сказал Екатерининский старик, презрительно обернувшись на Болконского.
– Маленькое именье ничего не приносило дохода, – отвечал Болконский, чтобы напрасно не раздражать старика, стараясь смягчить перед ним свой поступок.
– Vous craignez d'etre en retard, [Боитесь опоздать,] – сказал старик, глядя на Кочубея.
– Я одного не понимаю, – продолжал старик – кто будет землю пахать, коли им волю дать? Легко законы писать, а управлять трудно. Всё равно как теперь, я вас спрашиваю, граф, кто будет начальником палат, когда всем экзамены держать?
– Те, кто выдержат экзамены, я думаю, – отвечал Кочубей, закидывая ногу на ногу и оглядываясь.
– Вот у меня служит Пряничников, славный человек, золото человек, а ему 60 лет, разве он пойдет на экзамены?…
– Да, это затруднительно, понеже образование весьма мало распространено, но… – Граф Кочубей не договорил, он поднялся и, взяв за руку князя Андрея, пошел навстречу входящему высокому, лысому, белокурому человеку, лет сорока, с большим открытым лбом и необычайной, странной белизной продолговатого лица. На вошедшем был синий фрак, крест на шее и звезда на левой стороне груди. Это был Сперанский. Князь Андрей тотчас узнал его и в душе его что то дрогнуло, как это бывает в важные минуты жизни. Было ли это уважение, зависть, ожидание – он не знал. Вся фигура Сперанского имела особенный тип, по которому сейчас можно было узнать его. Ни у кого из того общества, в котором жил князь Андрей, он не видал этого спокойствия и самоуверенности неловких и тупых движений, ни у кого он не видал такого твердого и вместе мягкого взгляда полузакрытых и несколько влажных глаз, не видал такой твердости ничего незначащей улыбки, такого тонкого, ровного, тихого голоса, и, главное, такой нежной белизны лица и особенно рук, несколько широких, но необыкновенно пухлых, нежных и белых. Такую белизну и нежность лица князь Андрей видал только у солдат, долго пробывших в госпитале. Это был Сперанский, государственный секретарь, докладчик государя и спутник его в Эрфурте, где он не раз виделся и говорил с Наполеоном.
Сперанский не перебегал глазами с одного лица на другое, как это невольно делается при входе в большое общество, и не торопился говорить. Он говорил тихо, с уверенностью, что будут слушать его, и смотрел только на то лицо, с которым говорил.
Князь Андрей особенно внимательно следил за каждым словом и движением Сперанского. Как это бывает с людьми, особенно с теми, которые строго судят своих ближних, князь Андрей, встречаясь с новым лицом, особенно с таким, как Сперанский, которого он знал по репутации, всегда ждал найти в нем полное совершенство человеческих достоинств.
Сперанский сказал Кочубею, что жалеет о том, что не мог приехать раньше, потому что его задержали во дворце. Он не сказал, что его задержал государь. И эту аффектацию скромности заметил князь Андрей. Когда Кочубей назвал ему князя Андрея, Сперанский медленно перевел свои глаза на Болконского с той же улыбкой и молча стал смотреть на него.
– Я очень рад с вами познакомиться, я слышал о вас, как и все, – сказал он.
Кочубей сказал несколько слов о приеме, сделанном Болконскому Аракчеевым. Сперанский больше улыбнулся.
– Директором комиссии военных уставов мой хороший приятель – господин Магницкий, – сказал он, договаривая каждый слог и каждое слово, – и ежели вы того пожелаете, я могу свести вас с ним. (Он помолчал на точке.) Я надеюсь, что вы найдете в нем сочувствие и желание содействовать всему разумному.
Около Сперанского тотчас же составился кружок и тот старик, который говорил о своем чиновнике, Пряничникове, тоже с вопросом обратился к Сперанскому.
Князь Андрей, не вступая в разговор, наблюдал все движения Сперанского, этого человека, недавно ничтожного семинариста и теперь в руках своих, – этих белых, пухлых руках, имевшего судьбу России, как думал Болконский. Князя Андрея поразило необычайное, презрительное спокойствие, с которым Сперанский отвечал старику. Он, казалось, с неизмеримой высоты обращал к нему свое снисходительное слово. Когда старик стал говорить слишком громко, Сперанский улыбнулся и сказал, что он не может судить о выгоде или невыгоде того, что угодно было государю.
Поговорив несколько времени в общем кругу, Сперанский встал и, подойдя к князю Андрею, отозвал его с собой на другой конец комнаты. Видно было, что он считал нужным заняться Болконским.
– Я не успел поговорить с вами, князь, среди того одушевленного разговора, в который был вовлечен этим почтенным старцем, – сказал он, кротко презрительно улыбаясь и этой улыбкой как бы признавая, что он вместе с князем Андреем понимает ничтожность тех людей, с которыми он только что говорил. Это обращение польстило князю Андрею. – Я вас знаю давно: во первых, по делу вашему о ваших крестьянах, это наш первый пример, которому так желательно бы было больше последователей; а во вторых, потому что вы один из тех камергеров, которые не сочли себя обиженными новым указом о придворных чинах, вызывающим такие толки и пересуды.
– Да, – сказал князь Андрей, – отец не хотел, чтобы я пользовался этим правом; я начал службу с нижних чинов.
– Ваш батюшка, человек старого века, очевидно стоит выше наших современников, которые так осуждают эту меру, восстановляющую только естественную справедливость.
– Я думаю однако, что есть основание и в этих осуждениях… – сказал князь Андрей, стараясь бороться с влиянием Сперанского, которое он начинал чувствовать. Ему неприятно было во всем соглашаться с ним: он хотел противоречить. Князь Андрей, обыкновенно говоривший легко и хорошо, чувствовал теперь затруднение выражаться, говоря с Сперанским. Его слишком занимали наблюдения над личностью знаменитого человека.
– Основание для личного честолюбия может быть, – тихо вставил свое слово Сперанский.
– Отчасти и для государства, – сказал князь Андрей.
– Как вы разумеете?… – сказал Сперанский, тихо опустив глаза.
– Я почитатель Montesquieu, – сказал князь Андрей. – И его мысль о том, что le рrincipe des monarchies est l'honneur, me parait incontestable. Certains droits еt privileges de la noblesse me paraissent etre des moyens de soutenir ce sentiment. [основа монархий есть честь, мне кажется несомненной. Некоторые права и привилегии дворянства мне кажутся средствами для поддержания этого чувства.]
Улыбка исчезла на белом лице Сперанского и физиономия его много выиграла от этого. Вероятно мысль князя Андрея показалась ему занимательною.
– Si vous envisagez la question sous ce point de vue, [Если вы так смотрите на предмет,] – начал он, с очевидным затруднением выговаривая по французски и говоря еще медленнее, чем по русски, но совершенно спокойно. Он сказал, что честь, l'honneur, не может поддерживаться преимуществами вредными для хода службы, что честь, l'honneur, есть или: отрицательное понятие неделанья предосудительных поступков, или известный источник соревнования для получения одобрения и наград, выражающих его.
Доводы его были сжаты, просты и ясны.
Институт, поддерживающий эту честь, источник соревнования, есть институт, подобный Legion d'honneur [Ордену почетного легиона] великого императора Наполеона, не вредящий, а содействующий успеху службы, а не сословное или придворное преимущество.
– Я не спорю, но нельзя отрицать, что придворное преимущество достигло той же цели, – сказал князь Андрей: – всякий придворный считает себя обязанным достойно нести свое положение.
– Но вы им не хотели воспользоваться, князь, – сказал Сперанский, улыбкой показывая, что он, неловкий для своего собеседника спор, желает прекратить любезностью. – Ежели вы мне сделаете честь пожаловать ко мне в среду, – прибавил он, – то я, переговорив с Магницким, сообщу вам то, что может вас интересовать, и кроме того буду иметь удовольствие подробнее побеседовать с вами. – Он, закрыв глаза, поклонился, и a la francaise, [на французский манер,] не прощаясь, стараясь быть незамеченным, вышел из залы.


Первое время своего пребыванья в Петербурге, князь Андрей почувствовал весь свой склад мыслей, выработавшийся в его уединенной жизни, совершенно затемненным теми мелкими заботами, которые охватили его в Петербурге.
С вечера, возвращаясь домой, он в памятной книжке записывал 4 или 5 необходимых визитов или rendez vous [свиданий] в назначенные часы. Механизм жизни, распоряжение дня такое, чтобы везде поспеть во время, отнимали большую долю самой энергии жизни. Он ничего не делал, ни о чем даже не думал и не успевал думать, а только говорил и с успехом говорил то, что он успел прежде обдумать в деревне.
Он иногда замечал с неудовольствием, что ему случалось в один и тот же день, в разных обществах, повторять одно и то же. Но он был так занят целые дни, что не успевал подумать о том, что он ничего не думал.
Сперанский, как в первое свидание с ним у Кочубея, так и потом в середу дома, где Сперанский с глазу на глаз, приняв Болконского, долго и доверчиво говорил с ним, сделал сильное впечатление на князя Андрея.
Князь Андрей такое огромное количество людей считал презренными и ничтожными существами, так ему хотелось найти в другом живой идеал того совершенства, к которому он стремился, что он легко поверил, что в Сперанском он нашел этот идеал вполне разумного и добродетельного человека. Ежели бы Сперанский был из того же общества, из которого был князь Андрей, того же воспитания и нравственных привычек, то Болконский скоро бы нашел его слабые, человеческие, не геройские стороны, но теперь этот странный для него логический склад ума тем более внушал ему уважения, что он не вполне понимал его. Кроме того, Сперанский, потому ли что он оценил способности князя Андрея, или потому что нашел нужным приобресть его себе, Сперанский кокетничал перед князем Андреем своим беспристрастным, спокойным разумом и льстил князю Андрею той тонкой лестью, соединенной с самонадеянностью, которая состоит в молчаливом признавании своего собеседника с собою вместе единственным человеком, способным понимать всю глупость всех остальных, и разумность и глубину своих мыслей.
Во время длинного их разговора в середу вечером, Сперанский не раз говорил: «У нас смотрят на всё, что выходит из общего уровня закоренелой привычки…» или с улыбкой: «Но мы хотим, чтоб и волки были сыты и овцы целы…» или: «Они этого не могут понять…» и всё с таким выраженьем, которое говорило: «Мы: вы да я, мы понимаем, что они и кто мы ».
Этот первый, длинный разговор с Сперанским только усилил в князе Андрее то чувство, с которым он в первый раз увидал Сперанского. Он видел в нем разумного, строго мыслящего, огромного ума человека, энергией и упорством достигшего власти и употребляющего ее только для блага России. Сперанский в глазах князя Андрея был именно тот человек, разумно объясняющий все явления жизни, признающий действительным только то, что разумно, и ко всему умеющий прилагать мерило разумности, которым он сам так хотел быть. Всё представлялось так просто, ясно в изложении Сперанского, что князь Андрей невольно соглашался с ним во всем. Ежели он возражал и спорил, то только потому, что хотел нарочно быть самостоятельным и не совсем подчиняться мнениям Сперанского. Всё было так, всё было хорошо, но одно смущало князя Андрея: это был холодный, зеркальный, не пропускающий к себе в душу взгляд Сперанского, и его белая, нежная рука, на которую невольно смотрел князь Андрей, как смотрят обыкновенно на руки людей, имеющих власть. Зеркальный взгляд и нежная рука эта почему то раздражали князя Андрея. Неприятно поражало князя Андрея еще слишком большое презрение к людям, которое он замечал в Сперанском, и разнообразность приемов в доказательствах, которые он приводил в подтверждение своих мнений. Он употреблял все возможные орудия мысли, исключая сравнения, и слишком смело, как казалось князю Андрею, переходил от одного к другому. То он становился на почву практического деятеля и осуждал мечтателей, то на почву сатирика и иронически подсмеивался над противниками, то становился строго логичным, то вдруг поднимался в область метафизики. (Это последнее орудие доказательств он особенно часто употреблял.) Он переносил вопрос на метафизические высоты, переходил в определения пространства, времени, мысли и, вынося оттуда опровержения, опять спускался на почву спора.
Вообще главная черта ума Сперанского, поразившая князя Андрея, была несомненная, непоколебимая вера в силу и законность ума. Видно было, что никогда Сперанскому не могла притти в голову та обыкновенная для князя Андрея мысль, что нельзя всё таки выразить всего того, что думаешь, и никогда не приходило сомнение в том, что не вздор ли всё то, что я думаю и всё то, во что я верю? И этот то особенный склад ума Сперанского более всего привлекал к себе князя Андрея.
Первое время своего знакомства с Сперанским князь Андрей питал к нему страстное чувство восхищения, похожее на то, которое он когда то испытывал к Бонапарте. То обстоятельство, что Сперанский был сын священника, которого можно было глупым людям, как это и делали многие, пошло презирать в качестве кутейника и поповича, заставляло князя Андрея особенно бережно обходиться с своим чувством к Сперанскому, и бессознательно усиливать его в самом себе.
В тот первый вечер, который Болконский провел у него, разговорившись о комиссии составления законов, Сперанский с иронией рассказывал князю Андрею о том, что комиссия законов существует 150 лет, стоит миллионы и ничего не сделала, что Розенкампф наклеил ярлычки на все статьи сравнительного законодательства. – И вот и всё, за что государство заплатило миллионы! – сказал он.
– Мы хотим дать новую судебную власть Сенату, а у нас нет законов. Поэтому то таким людям, как вы, князь, грех не служить теперь.
Князь Андрей сказал, что для этого нужно юридическое образование, которого он не имеет.
– Да его никто не имеет, так что же вы хотите? Это circulus viciosus, [заколдованный круг,] из которого надо выйти усилием.

Через неделю князь Андрей был членом комиссии составления воинского устава, и, чего он никак не ожидал, начальником отделения комиссии составления вагонов. По просьбе Сперанского он взял первую часть составляемого гражданского уложения и, с помощью Code Napoleon и Justiniani, [Кодекса Наполеона и Юстиниана,] работал над составлением отдела: Права лиц.


Года два тому назад, в 1808 году, вернувшись в Петербург из своей поездки по имениям, Пьер невольно стал во главе петербургского масонства. Он устроивал столовые и надгробные ложи, вербовал новых членов, заботился о соединении различных лож и о приобретении подлинных актов. Он давал свои деньги на устройство храмин и пополнял, на сколько мог, сборы милостыни, на которые большинство членов были скупы и неаккуратны. Он почти один на свои средства поддерживал дом бедных, устроенный орденом в Петербурге. Жизнь его между тем шла по прежнему, с теми же увлечениями и распущенностью. Он любил хорошо пообедать и выпить, и, хотя и считал это безнравственным и унизительным, не мог воздержаться от увеселений холостых обществ, в которых он участвовал.
В чаду своих занятий и увлечений Пьер однако, по прошествии года, начал чувствовать, как та почва масонства, на которой он стоял, тем более уходила из под его ног, чем тверже он старался стать на ней. Вместе с тем он чувствовал, что чем глубже уходила под его ногами почва, на которой он стоял, тем невольнее он был связан с ней. Когда он приступил к масонству, он испытывал чувство человека, доверчиво становящего ногу на ровную поверхность болота. Поставив ногу, он провалился. Чтобы вполне увериться в твердости почвы, на которой он стоял, он поставил другую ногу и провалился еще больше, завяз и уже невольно ходил по колено в болоте.
Иосифа Алексеевича не было в Петербурге. (Он в последнее время отстранился от дел петербургских лож и безвыездно жил в Москве.) Все братья, члены лож, были Пьеру знакомые в жизни люди и ему трудно было видеть в них только братьев по каменьщичеству, а не князя Б., не Ивана Васильевича Д., которых он знал в жизни большею частию как слабых и ничтожных людей. Из под масонских фартуков и знаков он видел на них мундиры и кресты, которых они добивались в жизни. Часто, собирая милостыню и сочтя 20–30 рублей, записанных на приход, и большею частию в долг с десяти членов, из которых половина были так же богаты, как и он, Пьер вспоминал масонскую клятву о том, что каждый брат обещает отдать всё свое имущество для ближнего; и в душе его поднимались сомнения, на которых он старался не останавливаться.
Всех братьев, которых он знал, он подразделял на четыре разряда. К первому разряду он причислял братьев, не принимающих деятельного участия ни в делах лож, ни в делах человеческих, но занятых исключительно таинствами науки ордена, занятых вопросами о тройственном наименовании Бога, или о трех началах вещей, сере, меркурии и соли, или о значении квадрата и всех фигур храма Соломонова. Пьер уважал этот разряд братьев масонов, к которому принадлежали преимущественно старые братья, и сам Иосиф Алексеевич, по мнению Пьера, но не разделял их интересов. Сердце его не лежало к мистической стороне масонства.
Ко второму разряду Пьер причислял себя и себе подобных братьев, ищущих, колеблющихся, не нашедших еще в масонстве прямого и понятного пути, но надеющихся найти его.
К третьему разряду он причислял братьев (их было самое большое число), не видящих в масонстве ничего, кроме внешней формы и обрядности и дорожащих строгим исполнением этой внешней формы, не заботясь о ее содержании и значении. Таковы были Виларский и даже великий мастер главной ложи.
К четвертому разряду, наконец, причислялось тоже большое количество братьев, в особенности в последнее время вступивших в братство. Это были люди, по наблюдениям Пьера, ни во что не верующие, ничего не желающие, и поступавшие в масонство только для сближения с молодыми богатыми и сильными по связям и знатности братьями, которых весьма много было в ложе.
Пьер начинал чувствовать себя неудовлетворенным своей деятельностью. Масонство, по крайней мере то масонство, которое он знал здесь, казалось ему иногда, основано было на одной внешности. Он и не думал сомневаться в самом масонстве, но подозревал, что русское масонство пошло по ложному пути и отклонилось от своего источника. И потому в конце года Пьер поехал за границу для посвящения себя в высшие тайны ордена.

Летом еще в 1809 году, Пьер вернулся в Петербург. По переписке наших масонов с заграничными было известно, что Безухий успел за границей получить доверие многих высокопоставленных лиц, проник многие тайны, был возведен в высшую степень и везет с собою многое для общего блага каменьщического дела в России. Петербургские масоны все приехали к нему, заискивая в нем, и всем показалось, что он что то скрывает и готовит.
Назначено было торжественное заседание ложи 2 го градуса, в которой Пьер обещал сообщить то, что он имеет передать петербургским братьям от высших руководителей ордена. Заседание было полно. После обыкновенных обрядов Пьер встал и начал свою речь.
– Любезные братья, – начал он, краснея и запинаясь и держа в руке написанную речь. – Недостаточно блюсти в тиши ложи наши таинства – нужно действовать… действовать. Мы находимся в усыплении, а нам нужно действовать. – Пьер взял свою тетрадь и начал читать.
«Для распространения чистой истины и доставления торжества добродетели, читал он, должны мы очистить людей от предрассудков, распространить правила, сообразные с духом времени, принять на себя воспитание юношества, соединиться неразрывными узами с умнейшими людьми, смело и вместе благоразумно преодолевать суеверие, неверие и глупость, образовать из преданных нам людей, связанных между собою единством цели и имеющих власть и силу.
«Для достижения сей цели должно доставить добродетели перевес над пороком, должно стараться, чтобы честный человек обретал еще в сем мире вечную награду за свои добродетели. Но в сих великих намерениях препятствуют нам весьма много – нынешние политические учреждения. Что же делать при таковом положении вещей? Благоприятствовать ли революциям, всё ниспровергнуть, изгнать силу силой?… Нет, мы весьма далеки от того. Всякая насильственная реформа достойна порицания, потому что ни мало не исправит зла, пока люди остаются таковы, каковы они есть, и потому что мудрость не имеет нужды в насилии.
«Весь план ордена должен быть основан на том, чтоб образовать людей твердых, добродетельных и связанных единством убеждения, убеждения, состоящего в том, чтобы везде и всеми силами преследовать порок и глупость и покровительствовать таланты и добродетель: извлекать из праха людей достойных, присоединяя их к нашему братству. Тогда только орден наш будет иметь власть – нечувствительно вязать руки покровителям беспорядка и управлять ими так, чтоб они того не примечали. Одним словом, надобно учредить всеобщий владычествующий образ правления, который распространялся бы над целым светом, не разрушая гражданских уз, и при коем все прочие правления могли бы продолжаться обыкновенным своим порядком и делать всё, кроме того только, что препятствует великой цели нашего ордена, то есть доставлению добродетели торжества над пороком. Сию цель предполагало само христианство. Оно учило людей быть мудрыми и добрыми, и для собственной своей выгоды следовать примеру и наставлениям лучших и мудрейших человеков.
«Тогда, когда всё погружено было во мраке, достаточно было, конечно, одного проповедания: новость истины придавала ей особенную силу, но ныне потребны для нас гораздо сильнейшие средства. Теперь нужно, чтобы человек, управляемый своими чувствами, находил в добродетели чувственные прелести. Нельзя искоренить страстей; должно только стараться направить их к благородной цели, и потому надобно, чтобы каждый мог удовлетворять своим страстям в пределах добродетели, и чтобы наш орден доставлял к тому средства.
«Как скоро будет у нас некоторое число достойных людей в каждом государстве, каждый из них образует опять двух других, и все они тесно между собой соединятся – тогда всё будет возможно для ордена, который втайне успел уже сделать многое ко благу человечества».
Речь эта произвела не только сильное впечатление, но и волнение в ложе. Большинство же братьев, видевшее в этой речи опасные замыслы иллюминатства, с удивившею Пьера холодностью приняло его речь. Великий мастер стал возражать Пьеру. Пьер с большим и большим жаром стал развивать свои мысли. Давно не было столь бурного заседания. Составились партии: одни обвиняли Пьера, осуждая его в иллюминатстве; другие поддерживали его. Пьера в первый раз поразило на этом собрании то бесконечное разнообразие умов человеческих, которое делает то, что никакая истина одинаково не представляется двум людям. Даже те из членов, которые казалось были на его стороне, понимали его по своему, с ограничениями, изменениями, на которые он не мог согласиться, так как главная потребность Пьера состояла именно в том, чтобы передать свою мысль другому точно так, как он сам понимал ее.
По окончании заседания великий мастер с недоброжелательством и иронией сделал Безухому замечание о его горячности и о том, что не одна любовь к добродетели, но и увлечение борьбы руководило им в споре. Пьер не отвечал ему и коротко спросил, будет ли принято его предложение. Ему сказали, что нет, и Пьер, не дожидаясь обычных формальностей, вышел из ложи и уехал домой.


На Пьера опять нашла та тоска, которой он так боялся. Он три дня после произнесения своей речи в ложе лежал дома на диване, никого не принимая и никуда не выезжая.
В это время он получил письмо от жены, которая умоляла его о свидании, писала о своей грусти по нем и о желании посвятить ему всю свою жизнь.
В конце письма она извещала его, что на днях приедет в Петербург из за границы.
Вслед за письмом в уединение Пьера ворвался один из менее других уважаемых им братьев масонов и, наведя разговор на супружеские отношения Пьера, в виде братского совета, высказал ему мысль о том, что строгость его к жене несправедлива, и что Пьер отступает от первых правил масона, не прощая кающуюся.
В это же самое время теща его, жена князя Василья, присылала за ним, умоляя его хоть на несколько минут посетить ее для переговоров о весьма важном деле. Пьер видел, что был заговор против него, что его хотели соединить с женою, и это было даже не неприятно ему в том состоянии, в котором он находился. Ему было всё равно: Пьер ничто в жизни не считал делом большой важности, и под влиянием тоски, которая теперь овладела им, он не дорожил ни своею свободою, ни своим упорством в наказании жены.
«Никто не прав, никто не виноват, стало быть и она не виновата», думал он. – Ежели Пьер не изъявил тотчас же согласия на соединение с женою, то только потому, что в состоянии тоски, в котором он находился, он не был в силах ничего предпринять. Ежели бы жена приехала к нему, он бы теперь не прогнал ее. Разве не всё равно было в сравнении с тем, что занимало Пьера, жить или не жить с женою?
Не отвечая ничего ни жене, ни теще, Пьер раз поздним вечером собрался в дорогу и уехал в Москву, чтобы повидаться с Иосифом Алексеевичем. Вот что писал Пьер в дневнике своем.
«Москва, 17 го ноября.
Сейчас только приехал от благодетеля, и спешу записать всё, что я испытал при этом. Иосиф Алексеевич живет бедно и страдает третий год мучительною болезнью пузыря. Никто никогда не слыхал от него стона, или слова ропота. С утра и до поздней ночи, за исключением часов, в которые он кушает самую простую пищу, он работает над наукой. Он принял меня милостиво и посадил на кровати, на которой он лежал; я сделал ему знак рыцарей Востока и Иерусалима, он ответил мне тем же, и с кроткой улыбкой спросил меня о том, что я узнал и приобрел в прусских и шотландских ложах. Я рассказал ему всё, как умел, передав те основания, которые я предлагал в нашей петербургской ложе и сообщил о дурном приеме, сделанном мне, и о разрыве, происшедшем между мною и братьями. Иосиф Алексеевич, изрядно помолчав и подумав, на всё это изложил мне свой взгляд, который мгновенно осветил мне всё прошедшее и весь будущий путь, предлежащий мне. Он удивил меня, спросив о том, помню ли я, в чем состоит троякая цель ордена: 1) в хранении и познании таинства; 2) в очищении и исправлении себя для воспринятия оного и 3) в исправлении рода человеческого чрез стремление к таковому очищению. Какая есть главнейшая и первая цель из этих трех? Конечно собственное исправление и очищение. Только к этой цели мы можем всегда стремиться независимо от всех обстоятельств. Но вместе с тем эта то цель и требует от нас наиболее трудов, и потому, заблуждаясь гордостью, мы, упуская эту цель, беремся либо за таинство, которое недостойны воспринять по нечистоте своей, либо беремся за исправление рода человеческого, когда сами из себя являем пример мерзости и разврата. Иллюминатство не есть чистое учение именно потому, что оно увлеклось общественной деятельностью и преисполнено гордости. На этом основании Иосиф Алексеевич осудил мою речь и всю мою деятельность. Я согласился с ним в глубине души своей. По случаю разговора нашего о моих семейных делах, он сказал мне: – Главная обязанность истинного масона, как я сказал вам, состоит в совершенствовании самого себя. Но часто мы думаем, что, удалив от себя все трудности нашей жизни, мы скорее достигнем этой цели; напротив, государь мой, сказал он мне, только в среде светских волнений можем мы достигнуть трех главных целей: 1) самопознания, ибо человек может познавать себя только через сравнение, 2) совершенствования, только борьбой достигается оно, и 3) достигнуть главной добродетели – любви к смерти. Только превратности жизни могут показать нам тщету ее и могут содействовать – нашей врожденной любви к смерти или возрождению к новой жизни. Слова эти тем более замечательны, что Иосиф Алексеевич, несмотря на свои тяжкие физические страдания, никогда не тяготится жизнию, а любит смерть, к которой он, несмотря на всю чистоту и высоту своего внутреннего человека, не чувствует еще себя достаточно готовым. Потом благодетель объяснил мне вполне значение великого квадрата мироздания и указал на то, что тройственное и седьмое число суть основание всего. Он советовал мне не отстраняться от общения с петербургскими братьями и, занимая в ложе только должности 2 го градуса, стараться, отвлекая братьев от увлечений гордости, обращать их на истинный путь самопознания и совершенствования. Кроме того для себя лично советовал мне первее всего следить за самим собою, и с этою целью дал мне тетрадь, ту самую, в которой я пишу и буду вписывать впредь все свои поступки».
«Петербург, 23 го ноября.
«Я опять живу с женой. Теща моя в слезах приехала ко мне и сказала, что Элен здесь и что она умоляет меня выслушать ее, что она невинна, что она несчастна моим оставлением, и многое другое. Я знал, что ежели я только допущу себя увидать ее, то не в силах буду более отказать ей в ее желании. В сомнении своем я не знал, к чьей помощи и совету прибегнуть. Ежели бы благодетель был здесь, он бы сказал мне. Я удалился к себе, перечел письма Иосифа Алексеевича, вспомнил свои беседы с ним, и из всего вывел то, что я не должен отказывать просящему и должен подать руку помощи всякому, тем более человеку столь связанному со мною, и должен нести крест свой. Но ежели я для добродетели простил ее, то пускай и будет мое соединение с нею иметь одну духовную цель. Так я решил и так написал Иосифу Алексеевичу. Я сказал жене, что прошу ее забыть всё старое, прошу простить мне то, в чем я мог быть виноват перед нею, а что мне прощать ей нечего. Мне радостно было сказать ей это. Пусть она не знает, как тяжело мне было вновь увидать ее. Устроился в большом доме в верхних покоях и испытываю счастливое чувство обновления».


Как и всегда, и тогда высшее общество, соединяясь вместе при дворе и на больших балах, подразделялось на несколько кружков, имеющих каждый свой оттенок. В числе их самый обширный был кружок французский, Наполеоновского союза – графа Румянцева и Caulaincourt'a. В этом кружке одно из самых видных мест заняла Элен, как только она с мужем поселилась в Петербурге. У нее бывали господа французского посольства и большое количество людей, известных своим умом и любезностью, принадлежавших к этому направлению.
Элен была в Эрфурте во время знаменитого свидания императоров, и оттуда привезла эти связи со всеми Наполеоновскими достопримечательностями Европы. В Эрфурте она имела блестящий успех. Сам Наполеон, заметив ее в театре, сказал про нее: «C'est un superbe animal». [Это прекрасное животное.] Успех ее в качестве красивой и элегантной женщины не удивлял Пьера, потому что с годами она сделалась еще красивее, чем прежде. Но удивляло его то, что за эти два года жена его успела приобрести себе репутацию
«d'une femme charmante, aussi spirituelle, que belle». [прелестной женщины, столь же умной, сколько красивой.] Известный рrince de Ligne [князь де Линь] писал ей письма на восьми страницах. Билибин приберегал свои mots [словечки], чтобы в первый раз сказать их при графине Безуховой. Быть принятым в салоне графини Безуховой считалось дипломом ума; молодые люди прочитывали книги перед вечером Элен, чтобы было о чем говорить в ее салоне, и секретари посольства, и даже посланники, поверяли ей дипломатические тайны, так что Элен была сила в некотором роде. Пьер, который знал, что она была очень глупа, с странным чувством недоуменья и страха иногда присутствовал на ее вечерах и обедах, где говорилось о политике, поэзии и философии. На этих вечерах он испытывал чувство подобное тому, которое должен испытывать фокусник, ожидая всякий раз, что вот вот обман его откроется. Но оттого ли, что для ведения такого салона именно нужна была глупость, или потому что сами обманываемые находили удовольствие в этом обмане, обман не открывался, и репутация d'une femme charmante et spirituelle так непоколебимо утвердилась за Еленой Васильевной Безуховой, что она могла говорить самые большие пошлости и глупости, и всё таки все восхищались каждым ее словом и отыскивали в нем глубокий смысл, которого она сама и не подозревала.
Пьер был именно тем самым мужем, который нужен был для этой блестящей, светской женщины. Он был тот рассеянный чудак, муж grand seigneur [большой барин], никому не мешающий и не только не портящий общего впечатления высокого тона гостиной, но, своей противоположностью изяществу и такту жены, служащий выгодным для нее фоном. Пьер, за эти два года, вследствие своего постоянного сосредоточенного занятия невещественными интересами и искреннего презрения ко всему остальному, усвоил себе в неинтересовавшем его обществе жены тот тон равнодушия, небрежности и благосклонности ко всем, который не приобретается искусственно и который потому то и внушает невольное уважение. Он входил в гостиную своей жены как в театр, со всеми был знаком, всем был одинаково рад и ко всем был одинаково равнодушен. Иногда он вступал в разговор, интересовавший его, и тогда, без соображений о том, были ли тут или нет les messieurs de l'ambassade [служащие при посольстве], шамкая говорил свои мнения, которые иногда были совершенно не в тоне настоящей минуты. Но мнение о чудаке муже de la femme la plus distinguee de Petersbourg [самой замечательной женщины в Петербурге] уже так установилось, что никто не принимал au serux [всерьез] его выходок.
В числе многих молодых людей, ежедневно бывавших в доме Элен, Борис Друбецкой, уже весьма успевший в службе, был после возвращения Элен из Эрфурта, самым близким человеком в доме Безуховых. Элен называла его mon page [мой паж] и обращалась с ним как с ребенком. Улыбка ее в отношении его была та же, как и ко всем, но иногда Пьеру неприятно было видеть эту улыбку. Борис обращался с Пьером с особенной, достойной и грустной почтительностию. Этот оттенок почтительности тоже беспокоил Пьера. Пьер так больно страдал три года тому назад от оскорбления, нанесенного ему женой, что теперь он спасал себя от возможности подобного оскорбления во первых тем, что он не был мужем своей жены, во вторых тем, что он не позволял себе подозревать.
– Нет, теперь сделавшись bas bleu [синим чулком], она навсегда отказалась от прежних увлечений, – говорил он сам себе. – Не было примера, чтобы bas bleu имели сердечные увлечения, – повторял он сам себе неизвестно откуда извлеченное правило, которому несомненно верил. Но, странное дело, присутствие Бориса в гостиной жены (а он был почти постоянно), физически действовало на Пьера: оно связывало все его члены, уничтожало бессознательность и свободу его движений.