Магистерский курс C++ (МФТИ, 2022-2023). Лекция 4. Разрешение имён в шаблонах и One Definition Rule.

preview_player
Показать описание
Лекции в магистратуре МФТИ по современному C++ на русском языке. Кафедра микропроцессорных технологий.

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

Лектор: Константин Владимиров.
Дата лекции: 28 сентября 2022 года.
Съёмка и звук: Юлий Тарасов.

Timeline:
00:00 Имена и область видимости
06:45 Двухфазный процесс
12:30 Несколько примеров
20:35 Порядок частичных специализаций
24:40 Объявления и единицы трансляции
33:50 Связывание
44:40 One Definition Rule
50:00 Inline
59:10 ODR-usage
01:07:40 Выдача курсового проекта (язык ParaSL)

Errata:
* тут пока пусто
Рекомендации по теме
Комментарии
Автор

17:00 На 53 слайде вместо Base::exit(); должно быть Base<T>::exit();

ddvamp
Автор

54:40 "В годболте нет многомодульных программ"
jfyi сейчас это есть, при желании можете попробовать templates > C++ Cmake (ну или Add... > Tree (IDE mode)).

ivankorotkov
Автор

Константин, а возможны ли сценарии, в которых делают зависимым в принципе независимое выражение? Пример:

#include <iostream>
template <typename T> void foo(T) { std::cout << 'T'; }

struct S {};

template <typename>
struct dependent {};

template <typename T> void bar(T t, S s) { foo( (dependent<T>{}, void{}, s) ); foo(t); }

void foo(S) { std::cout << 'S'; }

int main()
{
bar(S{}, S{}); // SS
}

ddvamp
Автор

Вопрос по слайду 51: правильно ли я понимаю, что если бы был выбран любой встроенный тип (а не user-defined, S), то мы увидели бы на экране ТТ? И если да, то правильно ли я понимаю, что это связано с тем, что для встроенных типов множество связанных пространств имен - пустое, соответственно, на второй фазе разрешения имен компилятор бы просто не увидел определение foo(S)?

isnullxbh
Автор

@tilir
Константин, прошу прощения: по неведаной мне причине, я путаюсь в терминологии))
Многомодульные программы == многофайловые, в данном контексте модулем является конкретный экзепляр обьектного файла?
Хотя, видимо, путаница связана с UE Modules - там это чтото вроде плагина/dll)

evgenyrozhnowsky
Автор

поясните пожалуйста мою негрмотность, зачем использовать переходник типов (1:00) если все работает без него (gcc):
template <typename T1, typename T2> struct A
{
void func()
{
internal_func(T1 ());
}
private:
template <typename V> void internal_func(V) { cout << "all\n";}
void internal_func(int) { cout << "int\n";}
};

nowar
Автор

ParaSL. Интересно узнать, почему в нём считается корректным следующее:
- возможность опустить return при возвращении значения из функции (обычно легче увидеть return, чем его не увидеть);
- возможность делать так: f8 = f9 (легкий способ сломать себе ногу, зачем?);
- размер vector задается как constexpr и нельзя итерироваться по нему (почему не array/tuple? ощущение, что выполнен swap понятий vector и array).
Это всё только ради интереса или было найдено в каком-то реальном языке?

nevadawolf
Автор

а где происходит инстанцирование функции? к примеру на 15:00 при инстанцировании функции call_foo и вызове непосредственно foo(t) у нас вызовется foo(S), почему? Инстанцирование функции записывается в конце единице трансляции?

malloc
Автор

57:52 Почему получился разный аутпут, в первом случае 32764, во втором 32767

schibir
Автор

16:29 у вас тут, кажется, злая оговорка -- если в классе есть метод exit, то он и вызовется. чтобы это сломалось, метод обязательно должен быть в родительском шаблоне(!) класса. в следующем примере вы, в общем-то, это и показываете

sigasigasiga
Автор

40:11 а что за загадка про буратино? 🤔

sigasigasiga