Гость
Форумы / C++ [игнор отключен] [закрыт для гостей] / Компиляция шаблонов / 21 сообщений из 21, страница 1 из 1
01.05.2018, 15:38
    #39638711
Компиляция шаблонов
Знатоки С++, снова обращаюсь к вам за помощью. Пока только начинаю знакомиться с шаблонами, так что возник такой вопрос, буду благодарен, если кто на пальцах объяснит, как это работает.
Вот есть шаблонный класс vector, и есть у него оператор сравнения <. Делаем, напрмер, так:
Код: plaintext
1.
2.
3.
4.
5.
	
        vector<int> iv1, iv2;
	iv1.push_back(1);
	iv2.push_back(2);
	bool b = iv1 > iv2;


И все работает. А вот если попробовать сравнить векторы, в которых лежат объекты, не определяющие оператор сравнения, то возникнет ошибка компиляции. Так вот я не могу понять, как это работает. Ведь если использовать вектор с несравнимыми элементами, но не вызывать сравнение, то никаких ошибок не возникает. Но ведь оператор сравнения там все равно должен быть определен, и компилятор должен об него споткнуться. Получается, vector компилируется не полностью весь сразу, а по частям? То есть, его оператор < не компилируется, если нигде не вызывается и поэтому в этом случае ошибок не возникает? Или это как-то по другому устроено? Сам я, ввиду скудных знаний С++, в страшных исходниках стандартной библиотеки пока не могу разобраться.
...
Рейтинг: 0 / 0
01.05.2018, 15:54
    #39638716
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Компиляция шаблонов
Ржавый гвоздьПолучается, vector компилируется не полностью весь сразу, а по частям?

Шаблоны это всего лишь разновидность макросов. Так что да, они разворачиваются и
компилируются только в используемой части.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
01.05.2018, 16:01
    #39638720
Anatoly Moskovsky
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Компиляция шаблонов
Ржавый гвоздь,

Шаблон компилируется только в той части, которая используется.
А именно - компилируются только функции шаблона которые где либо вызываются и только шаблонные классы, которые где либо инстанцируются.
Если функция(шаблон) не вызывается, то она не компилируется, но при этом производится ее синтаксический разбор, т.е. она должна быть синтаксически корректным (например не должно быть пропущенных ";" и т.п. ).

Это называется SFINAE.

Соответственно оператор "<" для шаблона vector будет скомпилирован только если вы сравниваете вектора.
...
Рейтинг: 0 / 0
01.05.2018, 17:09
    #39638744
a guest
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Компиляция шаблонов
Ржавый гвоздь, операторы сравнения для векторов — это отдельные шаблонные функции. Естественно, пока они не используются, то не инстанциируются.
...
Рейтинг: 0 / 0
01.05.2018, 17:09
    #39638745
a guest
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Компиляция шаблонов
Anatoly MoskovskyШаблон компилируется только в той части, которая используется.
А именно - компилируются только функции шаблона которые где либо вызываются и только шаблонные классы, которые где либо инстанцируются.
Если функция(шаблон) не вызывается, то она не компилируется, но при этом производится ее синтаксический разбор, т.е. она должна быть синтаксически корректным (например не должно быть пропущенных ";" и т.п. ).

Это называется SFINAE.SFINAE называется не это.
...
Рейтинг: 0 / 0
01.05.2018, 17:31
    #39638752
Anatoly Moskovsky
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Компиляция шаблонов
a guestРжавый гвоздь, операторы сравнения для векторов — это отдельные шаблонные функции. Естественно, пока они не используются, то не инстанциируются.
Да, но ошибки нет не потому что они отдельные :)
a guestSFINAE называется не это.
Ну, да, SFINAE не совсем то же самое. Но непосредственно связанное свойство.
...
Рейтинг: 0 / 0
01.05.2018, 18:34
    #39638787
Компиляция шаблонов
Anatoly MoskovskyДа, но ошибки нет не потому что они отдельные :)

То есть, получается, компилируются только те функции шаблонного класса, которые где-либо вызываются?
...
Рейтинг: 0 / 0
01.05.2018, 18:49
    #39638793
Anatoly Moskovsky
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Компиляция шаблонов
Ржавый гвоздьТо есть, получается, компилируются только те функции шаблонного класса, которые где-либо вызываются?
Да.
...
Рейтинг: 0 / 0
03.05.2018, 10:11
    #39639209
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Компиляция шаблонов
Ржавый гвоздьAnatoly MoskovskyДа, но ошибки нет не потому что они отдельные :)

То есть, получается, компилируются только те функции шаблонного класса, которые где-либо вызываются?

Да, но грядут перемены и возможно после 20го года всё будет не так. (модули)
...
Рейтинг: 0 / 0
03.05.2018, 10:51
    #39639231
Anatoly Moskovsky
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Компиляция шаблонов
MasterZivДа, но грядут перемены и возможно после 20го года всё будет не так. (модули)
Модуль это всего лишь синтаксическое дерево куска кода без семантического разбора тех частей которые зависят от типа шаблона.
Они не заставляют инстанцировать весь этот код - компилятор сам будет выбирать из модуля что инстанцировать.
Поэтому с модулями будет то же самое.
...
Рейтинг: 0 / 0
03.05.2018, 13:32
    #39639382
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Компиляция шаблонов
Anatoly MoskovskyMasterZivДа, но грядут перемены и возможно после 20го года всё будет не так. (модули)
Модуль это всего лишь синтаксическое дерево куска кода без семантического разбора тех частей которые зависят от типа шаблона.
Они не заставляют инстанцировать весь этот код - компилятор сам будет выбирать из модуля что инстанцировать.
Поэтому с модулями будет то же самое.

Руку дашь на отсечение ? (можно также дать что-то другое...)
...
Рейтинг: 0 / 0
03.05.2018, 16:01
    #39639511
a guest
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Компиляция шаблонов
Anatoly Moskovskya guestSFINAE называется не это.
Ну, да, SFINAE не совсем то же самое. Но непосредственно связанное свойство.РАЗ ТУТ ТЕМКА ПРО ШАБЛОНЫ И SFINAE ЭТО ТИПА ПРО ШАБЛОНЫ ТОГДА ЗНАЧИТ НЕПОСРЕДСТВЕННО СВЯЗАННОЕ.

Откуда substitution failure, если вообще никакого substitution никуда не происходит???
...
Рейтинг: 0 / 0
04.05.2018, 14:22
    #39640062
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Компиляция шаблонов
Откуда substitution failure, если вообще никакого substitution никуда не происходит???

SFINAE это о другом вообще.

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

Вот когда такое происходит, и в случае одного или нескольких путей инстанциации происходит ошибка компиляции, то вот это как раз случай SFINAE , такая ошибка не должна играть роль, и компилятором должны быть рассмотрены другие пути инстанциации нужных шаблонов.
...
Рейтинг: 0 / 0
04.05.2018, 15:24
    #39640132
a guest
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Компиляция шаблонов
MasterZiv SFINAE это о другом вообще.Я это и пытался донести.
...
Рейтинг: 0 / 0
04.05.2018, 16:01
    #39640162
Anatoly Moskovsky
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Компиляция шаблонов
SFINAE возможно потому, что возможно не делать подстановку реально неиспользованых функций.
...
Рейтинг: 0 / 0
Период между сообщениями больше года.
28.04.2021, 11:05
    #40066601
tchingiz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Компиляция шаблонов
сколько функций для шаблона сгенерирует компилятор?
одну на все приложение или по одной в каждом скомпилированном файле?

1.h:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
template <class T> void swap1(T& l, T& r) {
  T t;
  t = l;
  l = r;
  r = t;
}
extern int f();



a.cpp:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
#include "1.h"

int f() {
   int a = 1, b = 2; 
   swap1(a, b);   
  return 0;
}



b.cpp:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
#include "1.h"

int main() {
   int a = 1, b = 2; 
   swap1(a, b);
   f();
   return 0;
}
...
Рейтинг: 0 / 0
28.04.2021, 11:54
    #40066631
a guest
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Компиляция шаблонов
...
Рейтинг: 0 / 0
28.04.2021, 21:13
    #40066991
Anatoly Moskovsky
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Компиляция шаблонов
tchingiz
сколько функций для шаблона сгенерирует компилятор?
одну на все приложение или по одной в каждом скомпилированном файле?

При компиляции будет сгенерирована по копии функции в каждой единице трансляции.
Далее компилятор проведет инлайнинг если посчитает нужным.
Для копий которые не заинлайнены, при линковке произойдет случайный выбор одной из них и останется только она.
Код же заинлайненых функций так и останется продублированным в каждом месте вызова. Что в принципе и ожидаемо.
...
Рейтинг: 0 / 0
29.04.2021, 00:10
    #40067032
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Компиляция шаблонов
Ржавый гвоздь
Знатоки С++, снова обращаюсь к вам за помощью. Пока только начинаю знакомиться с шаблонами, так что возник такой вопрос, буду благодарен, если кто на пальцах объяснит, как это работает.


Сразу книга что must be read: Вандервуд, Джосатис (Йозутис на самом деле) Шаблоны С++.

Ржавый гвоздь

Вот есть шаблонный класс vector, и есть у него оператор сравнения <. Делаем, напрмер, так:
Код: plaintext
1.
2.
3.
4.
5.
	
        vector<int> iv1, iv2;
	iv1.push_back(1);
	iv2.push_back(2);
	bool b = iv1 > iv2;


И все работает. А вот если попробовать сравнить векторы, в которых лежат объекты, не определяющие оператор сравнения, то возникнет ошибка компиляции. Так вот я не могу понять, как это работает. Ведь если использовать вектор с несравнимыми элементами, но не вызывать сравнение, то никаких ошибок не возникает.


Так и работает, самому вектору сравнение не нужно, и, если ты его не вызываешь, оно и не требуется.

Ржавый гвоздь

Но ведь оператор сравнения там все равно должен быть определен, и компилятор должен об него споткнуться.


Не должен, не споткнётся. сравнение самому вектору не нужно. Другим контейнерам иногда нужно -- например,
set, map (для ключа). А вектору сравнение элементов не нужно для работы.

Ржавый гвоздь

Получается, vector компилируется не полностью весь сразу, а по частям?


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

Ну да, "компилируется" по частам, это не секрет. на самом деле это не "компилируется", а "инстанциируется", инстанциируются элементы шаблона класса.
Да, по частям, только те, что нужны. Но , блин, где ты нашёл, что для вектора нужна операция сравнения элементов?
Где ты нашёл вообще операцию сравнения векторов?
Нету её в С++...

Ржавый гвоздь

Получается, vector компилируется не полностью весь сразу, а по частям?
То есть, его оператор < не компилируется, если нигде не вызывается и поэтому в этом случае ошибок не возникает? Или это как-то по другому устроено? Сам я, ввиду скудных знаний С++, в страшных исходниках стандартной библиотеки пока не могу разобраться.


Да, именно так.
...
Рейтинг: 0 / 0
29.04.2021, 05:07
    #40067051
Barlone
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Компиляция шаблонов
Ну так то операции сравнения для вектора есть. https://en.cppreference.com/w/cpp/container/vector/operator_cmp
...
Рейтинг: 0 / 0
29.04.2021, 07:11
    #40067063
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Компиляция шаблонов
Вы на даты смотрите. tchingiz зачем-то древнюю тему апнул с совсем другим вопросом.
...
Рейтинг: 0 / 0
Форумы / C++ [игнор отключен] [закрыт для гостей] / Компиляция шаблонов / 21 сообщений из 21, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]