Скачать презентацию Namespaces constexpr utility Namespaces Пространства имен Скачать презентацию Namespaces constexpr utility Namespaces Пространства имен

Namespaces_constexpr_utility.pptx

  • Количество слайдов: 28

Namespaces, constexpr, <utility> Namespaces, constexpr,

Namespaces | Пространства имен • Пространства имен – это способ избежать конфликта имен в Namespaces | Пространства имен • Пространства имен – это способ избежать конфликта имен в больших проектах. • Определения, находящиеся внутри пространства имен, доступны только внутри него. • Множественное определение одного и того же пространства имен является допустимым

Конфликты имён: подход языка Си В Си для избежания конфликта имен использовались префиксы struct Конфликты имён: подход языка Си В Си для избежания конфликта имен использовались префиксы struct XML_File { //. . . }; void XML_parse. File(XML_File *file); void XML_open. File(XML_File *file); void XML_close. File(XML_File *file); //. . .

Namespaces | Синтаксис 1. 2. 3. 4. 5. 6. 7. 8. namespace ns_name { Namespaces | Синтаксис 1. 2. 3. 4. 5. 6. 7. 8. namespace ns_name { declarations } inline namespace ns_name { declarations } (since C++11) namespace { declarations } ns_name: : name using namespace ns_name; using ns_name: : name; namespace name = qualified - namespace; namespace ns_name: : name (since C++17)

Namespaces|Описание пространства имен 1. Пространства имён могут быть вложенными namespace Ru { namespace Msk Namespaces|Описание пространства имен 1. Пространства имён могут быть вложенными namespace Ru { namespace Msk { namespace Your. Company. Namespace { class Array {}; } } } 2. Определение пространства имен можно разделить namespace N 1 N 2 N 1 { { void function(); } function() { /* do sth */ } } function() {} } function_2() { /* do sth else */ } }

Namespaces | Доступ к именам 1. Внутри namespace все имена доступны напрямую. 2. NS: Namespaces | Доступ к именам 1. Внутри namespace все имена доступны напрямую. 2. NS: : позволяет обратиться внутрь пространства имён NS. namespace NS { int get. Random. Number() { return 4; } } int i = NS: : get. Random. Number(); 3. Оператор : : позволяет обратится к глобальному пространству имён. class List { /*. . . */ }; namespace Facebook. Lib { class List { /*. . . */ }; : : List global. List; }

Namespaces | Глобальный namespace : : Global NS NS En Ru С помощью : Namespaces | Глобальный namespace : : Global NS NS En Ru С помощью : : можно получить доступ только к Global NS, но не к вышестоящему в иерархии. Чтобы обратится к En из Ru надо написать : : NS: : En

Namespaces | Name lookup Поиск имён – это процесс разрешения имени. 1. Если такое Namespaces | Name lookup Поиск имён – это процесс разрешения имени. 1. Если такое имя есть в текущем namespace, остановится и выдать все одноименные сущности в текущем namespace. 2. Если текущий namespace – глобальный, выдать ошибку. 3. Текущий namespace = Родительский namespace 4. Перейти на шаг 1 Примечание: поиск остановится как только нашел что-то. Перегрузка выполняется только для найденных имён.

Namespaces | Какая версия foo будет выбрана? int foo(int i) { return i; } Namespaces | Какая версия foo будет выбрана? int foo(int i) { return i; } namespace ru { int foo(float f) { return 2; } int foo(double a, double b) { return 3; } namespace spb { int global = foo(5); } } Как вызвать foo из глобального namespace?

Namespaces | Ключевое слово using int foo(int i) { return i; } namespace ru Namespaces | Ключевое слово using int foo(int i) { return i; } namespace ru { using : : foo; int foo(float f) { return 2; } int foo(double a, double b) { return 3; } namespace spb { int global = foo(5); } } Директива using в данном контексте добавляет foo из глобального namespace в поиск имён.

Namespace | LCA, using namespace NS int foo(int i) { return i; } namespace Namespace | LCA, using namespace NS int foo(int i) { return i; } namespace Ru { namespace Spb { int foo(int i) { return 1; } } namespace Msk { using namespace Spb; int foo(float f) { return 2; } int global = foo(5); } }

Namespaces | LCA, using namespace : : NS NS 1 NSl 1 NS 2 Namespaces | LCA, using namespace : : NS NS 1 NSl 1 NS 2 NSl 2 using namespace NSr 2 NSr 1 NSr 2

Namespaces | ADL, Поиск Кёнига namespace Graphic { struct Point 2 D { double Namespaces | ADL, Поиск Кёнига namespace Graphic { struct Point 2 D { double x; double y; Point 2 D() = default; Point 2 D(double x, double y) noexcept : x(x), y(y) {}; }; Point 2 D operator+(Point 2 D a, Point 2 D const& b) { return { a. x + b. x, a. y + b. y }; } std: : ostream& operator<<(std: : ostream& stream, Point 2 D const& point) { stream << point. x << ' ' << point. y; return stream; } }

Namespaces | ADL, Поиск Кёнига int main() { Graphic: : Point 2 D a(1, Namespaces | ADL, Поиск Кёнига int main() { Graphic: : Point 2 D a(1, 2); Graphic: : Point 2 D b(3, 4); std: : cout << a + b; } Вызовутся ли перегруженные операторы вывода и сложения, если исходить из правил поиска имён?

Namespaces | Безымянный namespace – это пространство имён, имя которого уникально (генерируется компилятором). namespace Namespaces | Безымянный namespace – это пространство имён, имя которого уникально (генерируется компилятором). namespace { struct Test { int value; }; } Всё равно, что: namespace $Generated. Name$ { struct Test { int value; }; } using namespace $Generated. Name$;

Namespaces | Вложенные пространства имен (С++17) namespace Subsystems { namespace Graphic { namespace Curves Namespaces | Вложенные пространства имен (С++17) namespace Subsystems { namespace Graphic { namespace Curves { //. . . } namespace Subsystems: : Graphic: : Curves{/*. . . */}

Namespaces | Синонимы пространств имён namespace SGC = Subsystems: : Graphic: : Curves; Имя Namespaces | Синонимы пространств имён namespace SGC = Subsystems: : Graphic: : Curves; Имя синонима Имя оригинала

Спецификатор constexpr в С++11 и в С++14 С помощью данного спецификатора можно создавать переменные, Спецификатор constexpr в С++11 и в С++14 С помощью данного спецификатора можно создавать переменные, функции и даже объекты, которые будут рассчитаны на этапе компиляции. constexpr int sum(int a, int b) { return a + b; } void func() { constexpr int c = sum(5, 12); }

constexpr - функция constexpr возвращаемое_значение имя_функции(параметры) Ключевое слово constexpr означает, что если фактические параметры constexpr - функция constexpr возвращаемое_значение имя_функции(параметры) Ключевое слово constexpr означает, что если фактические параметры являются значениями времени компиляции, то и сама функция должна вернуть результат времени компиляции

constexpr - переменная constexpr тип = expression; Создает константы времени компиляции, expression также должно constexpr - переменная constexpr тип = expression; Создает константы времени компиляции, expression также должно быть известно во время компиляции, причем constexpr переменная всегда является const, но constexpr не всегда является const

Пример с constexpr int sum(int a, int b) { return a + b; } Пример с constexpr int sum(int a, int b) { return a + b; } constexpr int new_sum(int a, int b) { return a + b; } void func() { constexpr int a 1 = new_sum(5, 12); constexpr int a 2 = sum(5, 12); int a 3 = new_sum(5, 12); int a 4 = sum(5, 12); }

Ограничения на constexpr - переменные Constexpr – переменная должна быть литеральным типом: • Скалярным Ограничения на constexpr - переменные Constexpr – переменная должна быть литеральным типом: • Скалярным типом • Указателем • Void (начиная с C++14) • Массивом скалярных типов • Классом, который удовлетворяет следующим условиям: • Имеет деструктор по умолчанию • Все нестатические члены класса должны быть литеральными типами • Класс должен иметь хотя бы один constexpr-конструктор (но не копирования / перемещения) или не иметь конструкторов вовсе

Ограничения на constexpr - переменные • Тип constexpr – переменной должен быть литеральным • Ограничения на constexpr - переменные • Тип constexpr – переменной должен быть литеральным • constexpr – переменная должна быть проинициализирована / д. б. вызван constexpr – конструктор • Параметры конструктора или присвоенное значение моогут содержать только литералы или constexpr – переменные и constexpr - функции

Ограничения на constexpr – функции /До С++14 • Не может быть виртуальной • Должна Ограничения на constexpr – функции /До С++14 • Не может быть виртуальной • Должна возвращать литеральный тип • Все параметры должны иметь литеральный тип • Тело функции должно содержать только следующее: • static_assert • typedef или using, которые объявляют типы, кроме классов и перечислений • using для указания видимости имен • Только один return, который может содержать литералы или constexpr переменные / функции

Как же тогда узнавать об ошибках? Единственный способ внятно узнать о логических ошибках в Как же тогда узнавать об ошибках? Единственный способ внятно узнать о логических ошибках в constexpr-функциях – кидать исключения. constexpr int div(int x, int y) { return (y == 0) ? throw std: : logic_error("x can't be zero") : (y / x); }

Изменения в С++14 • void стал литеральным типом • constexpr методы не являются const Изменения в С++14 • void стал литеральным типом • constexpr методы не являются const по умолчанию class Sample { constexpr int foo(int a); // C++11 - const // C++14 - non-const }; • Тело constexpr – функцц может содержать любые инструкции, кроме: • Ассемблерные вставки • Ключевое слово goto • static / thread_safe переменные должны инициализироваться при определении

STL – Вспомогательные средства Заголовок <utility> содержит определения: 1. Тип «пара» (std: : pair) STL – Вспомогательные средства Заголовок содержит определения: 1. Тип «пара» (std: : pair) 2. Namespace rel_ops (содержит шаблонные операторы сравнения) 3. Функции swap, move_if_noexcept, forward, make_pair, declval.

STL | Pair Определение: template <class T 1, class T 2> struct pair; Конструкторы: STL | Pair Определение: template struct pair; Конструкторы: constexpr pair(); pair(const T 1& x, const T 2& y); template pair(U 1&& x, U 2&& y); template pair(const pair && p); pair(const pair& p) = default; pair(pair&& p) = default;