SlideShare a Scribd company logo
Cpp0x Introduction
Некоторые особенности нового стандарта C++
                Вомпе Федор
Структура изложения
●   Немного из истории




●   Особенности нового стандарта
История стандарта C++
●   C++98
    ISO/IEC 14882:1998, первая версия стандарта от комитета
    JTC1/SC22/WG21, сам язык появился ~ 1983

●   C++2003
    ISO/IEC 14882:2003, скорректированная версия C++98

●   C++TR1 (2005)
    ISO/IEC TR 19768, C++ Library Extensions

●   C++0x (2011)
    ISO/IEC 14882:2011, первая крупная ревизия стандарта, добавление
    новых возможностей

●   C++TR2 (20??)
C++0x
Рассматриваются предложения(Proposals) по
измененению стандарта до 2006 года
Основные стадии работы над стандартом :
  ●   CD(Committee Draft)
  ●   FCD(Final Committee Draft)
      March 2010, Pittsburgh
  ●   FDIS(Final Draft International Standard)
      March 2011, Madrid
  ●   IS(International Standard) ?== FDIS
      ??, утверждение стандарта ISO, может занять около года
Что такое C++0x?
●   C++0x – следующая версия стандарта C++
●   “x” в названии – год утверждения стандарта,
    рассчитывали принять в 2008/2009 году. Теперь - “х” -
    шестнадцатиричное число (C++0B стандарт? )
Что говорят o С++0x?
●   “C++0x feels like a new language” - Bjarne Stroustrup, C++0x
    FAQ
●   “C++0x offers much more than “old” C++” - Scott Meyers,
    www.aristeia.com
Поддержка компиляторов
●   GCC 4.5.* (флаг -std=c++0x)
●   MSVC 10.0
●   IBM XLC/C++
●   Intel C++ Compiler 11.0




              http://wiki.apache.org/stdcxx/C++0xCompilerSupport
              http://www.aristeia.com/C++0x/C++0xFeatureAvailability.htm
Семантика перемещения
С++ построен на семантике копирования – ни компилятор, ни
разработчик не отслеживают временные объекты
   #include <iostream>
   #include <string>
   using namespace std;

   int main()
   {
      string s = string("h") + "e" + "ll" + "o";
      cout << s << endl;
   }
С++98/С++2003 – каждая операция сложения – создание новой
строки. C++0x - “добавление” строки к временной строке
=> Необходимость определения и задания lvalue и rvalue значений
lvalue's
lvalue – “левая часть” выражений, определяет объект с
длительным временем жизни
Обычно можно получить как адрес так и значение переменной
   char a [10];

   i;
   ++i;
   *&i;
   a[5];
   a[i];
Время жизни объекта контролируется разработчиком
rvalue's
rvalue – временные объекты, которые обычно живут до конца
выражения
Нельзя получить адрес rvalue переменной
   10
   i + 1
   i++

Время жизни объекта контролируется компилятором
С++0x: rvalue reference's
Предложены ~2002 году (N1385=02-0043)
Введение ссылок на временные объекты (rvalue
references), использование && для типа
Согласование с C++:
   ●   lvalue ссылка T& => изменяемые lvalue
   ●   lvalue ссылка T const& (i.e., const T&) => всевозможные
       modifiable/const lvalues and rvalues
   ●   rvalue ссылка T&& => только изменяемые rvalue     (Не
       лишайте прав невременных объектов ;) )
   ●   rvalue ссылка T const&& (i.e., const T&&) => modifiable/
       const rvalues;
Семантика копирования vs Семантика перемещения

Бенчмарк: один и тот же код работы STL с поддержкой C+
+0x(rvalue references && move semantics) и без его
поддержки, компилятор GCC 4.5.1
C:codecpp>move_n.exe
N = 3001
construction took 5.536
sort took 0.012
rotate took 0.001
destruction took 1.024
done
Total time = 6.573

C:codecpp>move_o.exe
N = 3001
construction took 16.899
sort took 11.254
rotate took 0.002
destruction took 1.254
done
Total time = 29.409

http://cpp-next.com/archive/2010/10/howards-stl-move-semantics-benchmark/
Что же лучше?
              30




              25




              20
время, сек.




              15




              10




               5




               0

                   construction    sort   rotate     destruction     Total time

                                          операции                 Move-enabled
                                                                   raw gcc
Неявное определение move-конструкций

Из “правила трёх” (Rule of Three) вырисовывается “правило
Пяти” (Rule of Five). Так или иначе должны быть определены :
   ●    Деструктор
   ●    Copy-конструктор
   ●    Copy-operator присаивания
   ●    Move-конструктор
   ●    Move-operator присваивания




Проблема: Как неявно доопределять недостающие конструкции?
Пример: нарушение инвариантов
#define _GLIBCXX_DEBUG
#include <iostream>
#include <vector>
struct X
{
    // invariant: v.size() == 5
    X() : v(5) {}

   //This move-constructor implicitly generated by compiler
   X(X&& r)
   {
       v = std::move(r.v);
   }

   ~X()
   {
       std::cout << v[0] << std::endl; //доступ к элементу которого уже нет ;(
   }

 private:
    std::vector<int> v;
};

int main()
{
    std::vector<X> y;
    y.push_back(X()); // X() rvalue: copied in C++03, moved in C++0x
}
Анализ и решение
Неявное задание move-конструкций нарушает инварианты =>
C++98/C++03 код несовместим со стандартом C++0x
●   Самое простое решение – отказаться от неявной генерации
    move-конструкций, оставить их явное задание
    (Dave Abrahams, “Implicit Move Must Go”, N3153=10-0143)
●   Другое решение – генерировать move-конструкции при
    определенных условиях => ограничение на содержание в
    классе rvalue's/const/reference значений
    (видимо, к этому решению склоняется комитет)
    В нашем случае – запрещаем генерировать move-конструктор т.к. есть
    деструктор, определенный пользователем(подробнее - n3203)
●   Еще решение – сделать C++0x несовместим с C++98/03
    (совсем не вариант, нет совместимости)
Лямбда-выражения
Лямбда-исчисление – фактически наука
   see for ex: John Harrison's “Introduction to Functional Programming course”,
   http://code.google.com/p/funprog-ru/

В программировании - вид записи анонимных(безымянных) функций (в C++
- функторов)
    ●   Обычно определяются в месте своего использования
    ●   В C++ представляют из себя короткую запись для функциональных
        объектов
    ●   Востребованы в многопоточных приложениях
Уже давно есть и успешно применяются в функциональных языках(ML,
Lisp, Erlang, ...) и в main-stream языках(python, php!, js). В Java – их нет.
“Lambdas, Lambdas Everywhere” - Herb Sutter on PDC 2010
Пример функционального объекта

class OddFunctor
{
public:
   OddFunctor(int& evenCount) : _evenCount(evenCount) { }

   void operator()(int n)
   {
      if (n % 2 == 0)
      {
         _evenCount++;
         cout << n;
      }
   }
private:
   int& _evenCount;
};
И его использование
int main()
{
   vector<int> v;
   for (int i = 0; i < 10; ++i)
   {
      v.push_back(i);
   }

    int evenCount = 0;

    for_each(v.begin(), v.end(), OddFunctor(evenCount));

    cout << "There are " << evenCount
         << " even numbers in the vector." << endl;
}
Тот же код с лямбдами
int main()
{
   vector<int> v;
   for (int i = 0; i < 10; ++i)
   {
      v.push_back(i);
   }

    int evenCount = 0;

    for_each(v.begin(), v.end(), [&evenCount] (int n) {
       if (n % 2 == 0)
       {
          evenCount++;
          cout << n << endl;
       }
    });

    cout << "There are " << evenCount
         << " even numbers in the vector." << endl;
}
Структура лямбда-выражения
[<список захвата>]
(<список параметров>) //опционально -> скобки можно не ставить
mutable throw(<список исключений>) //опционально
-> <тип возвращаемого значение> //опционально, вместе со стрелкой
{<тело лямбды>}

Список захвата :
 ●   &<имя переменной> - захват переменной по ссылке (=> замыкания)
 ●   <имя переменной> - захват переменной по значению
 ●   & - захват всех переменных по ссылке
 ●   = - захват всех переменных по значению
Список параметров – как у функции, перечисление <тип> <имя_параметра>
“mutable” – указывает на то, надо ли разрешать изменять переменные, захваченные
по значению
Примеры лямбда выражений
Числа Фиббоначи 1 :
vector<int> v;
v.resize(20);

generate(v.begin(), v.end(), [] {
    static int first = 0;
    static int second = 1;

   int ret = first;

   int new_second = first + second;
   first = second;
   second = new_second;

   return ret;
   });

for_each(v.begin(), v.end(), [] (int n) {
    cout << n << endl;
    });
Примеры лямбда выражений
Числа Фиббоначи 2 – рекурсивные лямбда-выражения
vector<int> v;
v.resize(20);

function<int(int)> fib2 = [&fib2](int n) -> int {
    static map<int,int> cache;

   if(n <= 2) { return 1; }
   else if(cache.find(n) == cache.end())
       {
       cache[n] = fib2(n-1) + fib2(n-2);
       }

   return cache[n];
   };

generate(v.begin(), v.end(), [] {
    static int n = 1;
    return fib2(2);
    });

for_each(v.begin(), v.end(), [] (int n) {
    cout << n << endl;
    });
Да, это тоже лямбда



      [](){}();
   // я тоже ∃
Ключевое слово auto
С++98 - ничего не делало
C++0x(N1984=06-0054) – определение типа по выражению :
    auto a = 7; // int
    auto b = 7.5; // double
    auto res = some_really_complicated_method<T, U>(v, a, b);

Использование с лямбдами :
    auto print_lambda = [] (int n) { cout << n; }
    ...
    for_each(v.begin(), v.end(), print_lambda);
Вместе с контейнерами STL :
   Было :
   for(vector<T>::const_iterator p = v.begin(); p!=v.end(); ++p)
       cout << *p << endl;

   Стало :
   for(auto p = v.begin(); p!=v.end(); ++p)
       cout << *p << endl;
Delegating Constructors
            (делегирование конструкторов)
Делегирование конструкторов способ использования уже
написанных конструкторов
   class X {
      int i_;
   Public :
      X( int i ) : i_(i) { }
      X() : X(42) { } // использование X(int), i_ == 42
   };
Поддерживаются только в IBM XLC++ 11.1
SC22/WG21/N1986 (revision 3)
Списки инициализации(Initializer Lists)

Initializer Lists(N2672=08-0182) – возможность создания и инициализации объекта
при помощи перечислений {..., ..., …}
Для использование с объектом класса необходим конструктор
std::initializer_list<тип>
      struct S {
             S(std::initializer_list<double>); // #1
             S(const std::string&); // #2
             // ...
      };
      const S& r1 = { 1, 2, 3.0 }; // #1
      const S& r2 { "Spinach" }; // #2
Два вида инициализации – с “=” и без
Полезно при использовании вместе с контейнерами(no push_back → push_back →
push_back way) :
    void foo(std::vector<int> v);
    ….
    foo({1, 2, 3, 4, 5});
Inheriting constructors
         (наследование конструкторов)
Что, если дочерним классам разрешить использовать конструкторы
базового класса для своего создания?
Синтаксис :
   struct B
   {
      B(int);
   };

   struct D : B
   {
     using B::B;
   };
Проблема : не поддерживает ни один компилятор, все еще
Proposal(N2540=08-0050), рассматривается вопрос об удалении из
стандарта(N3258=11-0028)
“Why doesn’t C++ have garbage collection? ……
  Because then there would be nothing left.”
Литература
●   JTC1/SC22/WG21 - The C++ Standards Committee
    http://www.open-std.org/jtc1/sc22/wg21/

●   Visual C++ Team Blog
    http://blogs.msdn.com/b/vcblog/

●   Bjarne Stroustroup – C++0x FAQ
    http://www2.research.att.com/~bs/C++0xFAQ.html

●   MSDN: What's New in Visual C++ 2010
    http://msdn.microsoft.com/en-us/library/dd465215.aspx
Cpp0x Introduction
Cpp0x Introduction
Bonus section
Raw and Unicode String Literals
Proposal : N2442, gcc 4.5/4.4
Unicode – добавление типов char16_t и char32_t, гарантирован
размер типа (кодировки UTF-16, and UTF-32)
Для каждого типа – свои строковые литералы(Unicode String Literals)
   char* a = "Hello, world!"; // обычный Hello world
   char16_t* b = u"Hello, world!"; // префикс для строкового литерала - u
   char32_t* c = U"Hello, World!"; // префикс для строкового литерала - U
Raw String Literals – позволяет неэкранировать слэши (RegExps!)
   char* fileLoc = "C:Program FilesCompanySomeFile.exe"; //так было
   char* fileLoc = R"(C:Program FilesCompanySomeFile.exe)";
Fixed-Size Integer Types
Типы фиксированного размера – взяты из TR1 (ns std::tr1)
●   int8_t, int16_t int32_t, int64_t
●   int_least8_t, int_least16_t, int_least32_t, int_least64_t
●   int_fast8_t, int_fast16_t, int_fast32_t, int_fast64_t

+ unsigned types uint##_t
Стандарт : 18.4 Integer Types
В литературе: Pete Becker "The C++ Standard Library Extensions".
It's nulltptr!
Как вызвать func(char* ) для следующего кода?
   void func(int);
   void func(char *);
   int main()
   {
      func(0); // вызовется func(int)
   }

С++98/03 решение :
   func( (char *)0); // ugly

С++0x решение :
   введем ключевое слово nullptr, будет обозначать нулевые указатели
   func(nullptr);
Использование nullptr
char* ch = nullptr;      //   ch со значением nullptr
char* ch2 = 0;           //   ch2 со значением nullptr
int n = nullptr;         //   ошибка
int n2 = 0;              //   n2 ноль

if(   ch == 0 );         //   истина
if(   ch == nullptr );   //   истина
if(   ch );              //   ложь
if(   n2 == 0 );         //   истина
if(   n2 == nullptr );   //   ошибка
if(   nullptr );         //   ошибка, nullptr не приводим к bool
if(   nullptr == 0 );    //   ошибка

// Арифметика
nullptr = 0;             // ошибка, nullptr не является lvalue
nullptr + 2;             // ошибка
Cpp0x Introduction

More Related Content

What's hot (20)

PDF
ПВТ - весна 2015 - Лекция 5. Многопоточное программирование в С++. Синхрониза...
Alexey Paznikov
 
PPTX
Евгений Зуев, С++ в России: Стандарт языка и его реализация
Platonov Sergey
 
PDF
ПВТ - осень 2014 - Лекция 5 - Многопоточное программирование в языке С++. Р...
Alexey Paznikov
 
PPTX
Некоторые паттерны реализации полиморфного поведения в C++ – Дмитрий Леванов,...
Yandex
 
PDF
Павел Сушин «Асинхронное программирование на С++: callbacks, futures, fibers»
Platonov Sergey
 
PPTX
Александр Фокин, Рефлексия в C++
Sergey Platonov
 
PDF
ПВТ - весна 2015 - Лекция 4. Шаблоны многопоточного программирования
Alexey Paznikov
 
PDF
Clojure #1
Alexander Podkhalyuzin
 
PDF
Игорь Кудрин, «Используем неизменяемые данные и создаем качественный код»
Platonov Sergey
 
PPTX
Использование шаблонов и RTTI для конфигурации симулятора флеш-накопителя - Г...
Yandex
 
PPTX
Никита Глушков, К вопросу о реализации кроссплатформенных фреймворков
Sergey Platonov
 
PDF
Антон Полухин, Немного о Boost
Sergey Platonov
 
PPTX
Статический анализ кода
Pavel Tsukanov
 
PDF
Полухин Антон, Как делать не надо: C++ велосипедостроение для профессионалов
Sergey Platonov
 
PDF
ПВТ - осень 2014 - Лекция 6 - Атомарные операции. Внеочередное выполнение инс...
Alexey Paznikov
 
PDF
Clojure #2 (2014)
Alexander Podkhalyuzin
 
PDF
ПВТ - весна 2015 - Лекция 3. Реентерабельность. Сигналы. Локальные данные пот...
Alexey Paznikov
 
PDF
Дмитрий Прокопцев — R-ссылки в С++11
Yandex
 
PDF
Григорий Демченко, “Асинхронность и сопрограммы: обработка данных“
Platonov Sergey
 
PDF
Догнать и перегнать boost::lexical_cast
Roman Orlov
 
ПВТ - весна 2015 - Лекция 5. Многопоточное программирование в С++. Синхрониза...
Alexey Paznikov
 
Евгений Зуев, С++ в России: Стандарт языка и его реализация
Platonov Sergey
 
ПВТ - осень 2014 - Лекция 5 - Многопоточное программирование в языке С++. Р...
Alexey Paznikov
 
Некоторые паттерны реализации полиморфного поведения в C++ – Дмитрий Леванов,...
Yandex
 
Павел Сушин «Асинхронное программирование на С++: callbacks, futures, fibers»
Platonov Sergey
 
Александр Фокин, Рефлексия в C++
Sergey Platonov
 
ПВТ - весна 2015 - Лекция 4. Шаблоны многопоточного программирования
Alexey Paznikov
 
Игорь Кудрин, «Используем неизменяемые данные и создаем качественный код»
Platonov Sergey
 
Использование шаблонов и RTTI для конфигурации симулятора флеш-накопителя - Г...
Yandex
 
Никита Глушков, К вопросу о реализации кроссплатформенных фреймворков
Sergey Platonov
 
Антон Полухин, Немного о Boost
Sergey Platonov
 
Статический анализ кода
Pavel Tsukanov
 
Полухин Антон, Как делать не надо: C++ велосипедостроение для профессионалов
Sergey Platonov
 
ПВТ - осень 2014 - Лекция 6 - Атомарные операции. Внеочередное выполнение инс...
Alexey Paznikov
 
Clojure #2 (2014)
Alexander Podkhalyuzin
 
ПВТ - весна 2015 - Лекция 3. Реентерабельность. Сигналы. Локальные данные пот...
Alexey Paznikov
 
Дмитрий Прокопцев — R-ссылки в С++11
Yandex
 
Григорий Демченко, “Асинхронность и сопрограммы: обработка данных“
Platonov Sergey
 
Догнать и перегнать boost::lexical_cast
Roman Orlov
 

Similar to Cpp0x Introduction (20)

PPTX
СИ++ УМЕР. ДА ЗДРАВСТВУЕТ СИ++
Pavel Tsukanov
 
PPTX
C++0x
alenacpp
 
PDF
Объектно-ориентированное программирование. Лекции 9 и 10
Dima Dzuba
 
PDF
C++ for real_programmers
daemon025
 
PDF
книга с++
Serghei Urban
 
PDF
C++ осень 2012 лекция 6
Technopark
 
PDF
C++ осень 2013 лекция 7
Technopark
 
PDF
C++ STL & Qt. Занятие 11.
Igor Shkulipa
 
PDF
C++ Базовый. Занятие 09.
Igor Shkulipa
 
PDF
C++ Базовый. Занятие 02.
Igor Shkulipa
 
PDF
Основы программирования на C++
Olga Maksimenkova
 
PPTX
особенности программирования на с++
mcroitor
 
PPT
C++ tema 1
krisT7
 
PDF
Step cpp0201
Evgenij Laktionov
 
PDF
C++ осень 2013 лекция 4
Technopark
 
PDF
C++ весна 2014 лекция 5
Technopark
 
PPTX
Михаил Матросов, “С++ без new и delete”
Platonov Sergey
 
PDF
C++ Базовый. Занятие 03.
Igor Shkulipa
 
PDF
Объектно-Ориентированное Программирование на C++, Лекции 3 и 4
Dima Dzuba
 
СИ++ УМЕР. ДА ЗДРАВСТВУЕТ СИ++
Pavel Tsukanov
 
C++0x
alenacpp
 
Объектно-ориентированное программирование. Лекции 9 и 10
Dima Dzuba
 
C++ for real_programmers
daemon025
 
книга с++
Serghei Urban
 
C++ осень 2012 лекция 6
Technopark
 
C++ осень 2013 лекция 7
Technopark
 
C++ STL & Qt. Занятие 11.
Igor Shkulipa
 
C++ Базовый. Занятие 09.
Igor Shkulipa
 
C++ Базовый. Занятие 02.
Igor Shkulipa
 
Основы программирования на C++
Olga Maksimenkova
 
особенности программирования на с++
mcroitor
 
C++ tema 1
krisT7
 
Step cpp0201
Evgenij Laktionov
 
C++ осень 2013 лекция 4
Technopark
 
C++ весна 2014 лекция 5
Technopark
 
Михаил Матросов, “С++ без new и delete”
Platonov Sergey
 
C++ Базовый. Занятие 03.
Igor Shkulipa
 
Объектно-Ориентированное Программирование на C++, Лекции 3 и 4
Dima Dzuba
 
Ad

Cpp0x Introduction

  • 2. Некоторые особенности нового стандарта C++ Вомпе Федор
  • 3. Структура изложения ● Немного из истории ● Особенности нового стандарта
  • 4. История стандарта C++ ● C++98 ISO/IEC 14882:1998, первая версия стандарта от комитета JTC1/SC22/WG21, сам язык появился ~ 1983 ● C++2003 ISO/IEC 14882:2003, скорректированная версия C++98 ● C++TR1 (2005) ISO/IEC TR 19768, C++ Library Extensions ● C++0x (2011) ISO/IEC 14882:2011, первая крупная ревизия стандарта, добавление новых возможностей ● C++TR2 (20??)
  • 5. C++0x Рассматриваются предложения(Proposals) по измененению стандарта до 2006 года Основные стадии работы над стандартом : ● CD(Committee Draft) ● FCD(Final Committee Draft) March 2010, Pittsburgh ● FDIS(Final Draft International Standard) March 2011, Madrid ● IS(International Standard) ?== FDIS ??, утверждение стандарта ISO, может занять около года
  • 6. Что такое C++0x? ● C++0x – следующая версия стандарта C++ ● “x” в названии – год утверждения стандарта, рассчитывали принять в 2008/2009 году. Теперь - “х” - шестнадцатиричное число (C++0B стандарт? )
  • 7. Что говорят o С++0x? ● “C++0x feels like a new language” - Bjarne Stroustrup, C++0x FAQ ● “C++0x offers much more than “old” C++” - Scott Meyers, www.aristeia.com
  • 8. Поддержка компиляторов ● GCC 4.5.* (флаг -std=c++0x) ● MSVC 10.0 ● IBM XLC/C++ ● Intel C++ Compiler 11.0 http://wiki.apache.org/stdcxx/C++0xCompilerSupport http://www.aristeia.com/C++0x/C++0xFeatureAvailability.htm
  • 9. Семантика перемещения С++ построен на семантике копирования – ни компилятор, ни разработчик не отслеживают временные объекты #include <iostream> #include <string> using namespace std; int main() { string s = string("h") + "e" + "ll" + "o"; cout << s << endl; } С++98/С++2003 – каждая операция сложения – создание новой строки. C++0x - “добавление” строки к временной строке => Необходимость определения и задания lvalue и rvalue значений
  • 10. lvalue's lvalue – “левая часть” выражений, определяет объект с длительным временем жизни Обычно можно получить как адрес так и значение переменной char a [10]; i; ++i; *&i; a[5]; a[i]; Время жизни объекта контролируется разработчиком
  • 11. rvalue's rvalue – временные объекты, которые обычно живут до конца выражения Нельзя получить адрес rvalue переменной 10 i + 1 i++ Время жизни объекта контролируется компилятором
  • 12. С++0x: rvalue reference's Предложены ~2002 году (N1385=02-0043) Введение ссылок на временные объекты (rvalue references), использование && для типа Согласование с C++: ● lvalue ссылка T& => изменяемые lvalue ● lvalue ссылка T const& (i.e., const T&) => всевозможные modifiable/const lvalues and rvalues ● rvalue ссылка T&& => только изменяемые rvalue (Не лишайте прав невременных объектов ;) ) ● rvalue ссылка T const&& (i.e., const T&&) => modifiable/ const rvalues;
  • 13. Семантика копирования vs Семантика перемещения Бенчмарк: один и тот же код работы STL с поддержкой C+ +0x(rvalue references && move semantics) и без его поддержки, компилятор GCC 4.5.1 C:codecpp>move_n.exe N = 3001 construction took 5.536 sort took 0.012 rotate took 0.001 destruction took 1.024 done Total time = 6.573 C:codecpp>move_o.exe N = 3001 construction took 16.899 sort took 11.254 rotate took 0.002 destruction took 1.254 done Total time = 29.409 http://cpp-next.com/archive/2010/10/howards-stl-move-semantics-benchmark/
  • 14. Что же лучше? 30 25 20 время, сек. 15 10 5 0 construction sort rotate destruction Total time операции Move-enabled raw gcc
  • 15. Неявное определение move-конструкций Из “правила трёх” (Rule of Three) вырисовывается “правило Пяти” (Rule of Five). Так или иначе должны быть определены : ● Деструктор ● Copy-конструктор ● Copy-operator присаивания ● Move-конструктор ● Move-operator присваивания Проблема: Как неявно доопределять недостающие конструкции?
  • 16. Пример: нарушение инвариантов #define _GLIBCXX_DEBUG #include <iostream> #include <vector> struct X { // invariant: v.size() == 5 X() : v(5) {} //This move-constructor implicitly generated by compiler X(X&& r) { v = std::move(r.v); } ~X() { std::cout << v[0] << std::endl; //доступ к элементу которого уже нет ;( } private: std::vector<int> v; }; int main() { std::vector<X> y; y.push_back(X()); // X() rvalue: copied in C++03, moved in C++0x }
  • 17. Анализ и решение Неявное задание move-конструкций нарушает инварианты => C++98/C++03 код несовместим со стандартом C++0x ● Самое простое решение – отказаться от неявной генерации move-конструкций, оставить их явное задание (Dave Abrahams, “Implicit Move Must Go”, N3153=10-0143) ● Другое решение – генерировать move-конструкции при определенных условиях => ограничение на содержание в классе rvalue's/const/reference значений (видимо, к этому решению склоняется комитет) В нашем случае – запрещаем генерировать move-конструктор т.к. есть деструктор, определенный пользователем(подробнее - n3203) ● Еще решение – сделать C++0x несовместим с C++98/03 (совсем не вариант, нет совместимости)
  • 18. Лямбда-выражения Лямбда-исчисление – фактически наука see for ex: John Harrison's “Introduction to Functional Programming course”, http://code.google.com/p/funprog-ru/ В программировании - вид записи анонимных(безымянных) функций (в C++ - функторов) ● Обычно определяются в месте своего использования ● В C++ представляют из себя короткую запись для функциональных объектов ● Востребованы в многопоточных приложениях Уже давно есть и успешно применяются в функциональных языках(ML, Lisp, Erlang, ...) и в main-stream языках(python, php!, js). В Java – их нет. “Lambdas, Lambdas Everywhere” - Herb Sutter on PDC 2010
  • 19. Пример функционального объекта class OddFunctor { public: OddFunctor(int& evenCount) : _evenCount(evenCount) { } void operator()(int n) { if (n % 2 == 0) { _evenCount++; cout << n; } } private: int& _evenCount; };
  • 20. И его использование int main() { vector<int> v; for (int i = 0; i < 10; ++i) { v.push_back(i); } int evenCount = 0; for_each(v.begin(), v.end(), OddFunctor(evenCount)); cout << "There are " << evenCount << " even numbers in the vector." << endl; }
  • 21. Тот же код с лямбдами int main() { vector<int> v; for (int i = 0; i < 10; ++i) { v.push_back(i); } int evenCount = 0; for_each(v.begin(), v.end(), [&evenCount] (int n) { if (n % 2 == 0) { evenCount++; cout << n << endl; } }); cout << "There are " << evenCount << " even numbers in the vector." << endl; }
  • 22. Структура лямбда-выражения [<список захвата>] (<список параметров>) //опционально -> скобки можно не ставить mutable throw(<список исключений>) //опционально -> <тип возвращаемого значение> //опционально, вместе со стрелкой {<тело лямбды>} Список захвата : ● &<имя переменной> - захват переменной по ссылке (=> замыкания) ● <имя переменной> - захват переменной по значению ● & - захват всех переменных по ссылке ● = - захват всех переменных по значению Список параметров – как у функции, перечисление <тип> <имя_параметра> “mutable” – указывает на то, надо ли разрешать изменять переменные, захваченные по значению
  • 23. Примеры лямбда выражений Числа Фиббоначи 1 : vector<int> v; v.resize(20); generate(v.begin(), v.end(), [] { static int first = 0; static int second = 1; int ret = first; int new_second = first + second; first = second; second = new_second; return ret; }); for_each(v.begin(), v.end(), [] (int n) { cout << n << endl; });
  • 24. Примеры лямбда выражений Числа Фиббоначи 2 – рекурсивные лямбда-выражения vector<int> v; v.resize(20); function<int(int)> fib2 = [&fib2](int n) -> int { static map<int,int> cache; if(n <= 2) { return 1; } else if(cache.find(n) == cache.end()) { cache[n] = fib2(n-1) + fib2(n-2); } return cache[n]; }; generate(v.begin(), v.end(), [] { static int n = 1; return fib2(2); }); for_each(v.begin(), v.end(), [] (int n) { cout << n << endl; });
  • 25. Да, это тоже лямбда [](){}(); // я тоже ∃
  • 26. Ключевое слово auto С++98 - ничего не делало C++0x(N1984=06-0054) – определение типа по выражению : auto a = 7; // int auto b = 7.5; // double auto res = some_really_complicated_method<T, U>(v, a, b); Использование с лямбдами : auto print_lambda = [] (int n) { cout << n; } ... for_each(v.begin(), v.end(), print_lambda); Вместе с контейнерами STL : Было : for(vector<T>::const_iterator p = v.begin(); p!=v.end(); ++p) cout << *p << endl; Стало : for(auto p = v.begin(); p!=v.end(); ++p) cout << *p << endl;
  • 27. Delegating Constructors (делегирование конструкторов) Делегирование конструкторов способ использования уже написанных конструкторов class X { int i_; Public : X( int i ) : i_(i) { } X() : X(42) { } // использование X(int), i_ == 42 }; Поддерживаются только в IBM XLC++ 11.1 SC22/WG21/N1986 (revision 3)
  • 28. Списки инициализации(Initializer Lists) Initializer Lists(N2672=08-0182) – возможность создания и инициализации объекта при помощи перечислений {..., ..., …} Для использование с объектом класса необходим конструктор std::initializer_list<тип> struct S { S(std::initializer_list<double>); // #1 S(const std::string&); // #2 // ... }; const S& r1 = { 1, 2, 3.0 }; // #1 const S& r2 { "Spinach" }; // #2 Два вида инициализации – с “=” и без Полезно при использовании вместе с контейнерами(no push_back → push_back → push_back way) : void foo(std::vector<int> v); …. foo({1, 2, 3, 4, 5});
  • 29. Inheriting constructors (наследование конструкторов) Что, если дочерним классам разрешить использовать конструкторы базового класса для своего создания? Синтаксис : struct B { B(int); }; struct D : B { using B::B; }; Проблема : не поддерживает ни один компилятор, все еще Proposal(N2540=08-0050), рассматривается вопрос об удалении из стандарта(N3258=11-0028)
  • 30. “Why doesn’t C++ have garbage collection? …… Because then there would be nothing left.”
  • 31. Литература ● JTC1/SC22/WG21 - The C++ Standards Committee http://www.open-std.org/jtc1/sc22/wg21/ ● Visual C++ Team Blog http://blogs.msdn.com/b/vcblog/ ● Bjarne Stroustroup – C++0x FAQ http://www2.research.att.com/~bs/C++0xFAQ.html ● MSDN: What's New in Visual C++ 2010 http://msdn.microsoft.com/en-us/library/dd465215.aspx
  • 35. Raw and Unicode String Literals Proposal : N2442, gcc 4.5/4.4 Unicode – добавление типов char16_t и char32_t, гарантирован размер типа (кодировки UTF-16, and UTF-32) Для каждого типа – свои строковые литералы(Unicode String Literals) char* a = "Hello, world!"; // обычный Hello world char16_t* b = u"Hello, world!"; // префикс для строкового литерала - u char32_t* c = U"Hello, World!"; // префикс для строкового литерала - U Raw String Literals – позволяет неэкранировать слэши (RegExps!) char* fileLoc = "C:Program FilesCompanySomeFile.exe"; //так было char* fileLoc = R"(C:Program FilesCompanySomeFile.exe)";
  • 36. Fixed-Size Integer Types Типы фиксированного размера – взяты из TR1 (ns std::tr1) ● int8_t, int16_t int32_t, int64_t ● int_least8_t, int_least16_t, int_least32_t, int_least64_t ● int_fast8_t, int_fast16_t, int_fast32_t, int_fast64_t + unsigned types uint##_t Стандарт : 18.4 Integer Types В литературе: Pete Becker "The C++ Standard Library Extensions".
  • 37. It's nulltptr! Как вызвать func(char* ) для следующего кода? void func(int); void func(char *); int main() { func(0); // вызовется func(int) } С++98/03 решение : func( (char *)0); // ugly С++0x решение : введем ключевое слово nullptr, будет обозначать нулевые указатели func(nullptr);
  • 38. Использование nullptr char* ch = nullptr; // ch со значением nullptr char* ch2 = 0; // ch2 со значением nullptr int n = nullptr; // ошибка int n2 = 0; // n2 ноль if( ch == 0 ); // истина if( ch == nullptr ); // истина if( ch ); // ложь if( n2 == 0 ); // истина if( n2 == nullptr ); // ошибка if( nullptr ); // ошибка, nullptr не приводим к bool if( nullptr == 0 ); // ошибка // Арифметика nullptr = 0; // ошибка, nullptr не является lvalue nullptr + 2; // ошибка