Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / C++ Новый топик    Ответить
 Компиляция шаблонов  [new]
Ржавый гвоздь
Member

Откуда:
Сообщений: 137
Знатоки С++, снова обращаюсь к вам за помощью. Пока только начинаю знакомиться с шаблонами, так что возник такой вопрос, буду благодарен, если кто на пальцах объяснит, как это работает.
Вот есть шаблонный класс vector, и есть у него оператор сравнения <. Делаем, напрмер, так:
	
        vector<int> iv1, iv2;
	iv1.push_back(1);
	iv2.push_back(2);
	bool b = iv1 > iv2;

И все работает. А вот если попробовать сравнить векторы, в которых лежат объекты, не определяющие оператор сравнения, то возникнет ошибка компиляции. Так вот я не могу понять, как это работает. Ведь если использовать вектор с несравнимыми элементами, но не вызывать сравнение, то никаких ошибок не возникает. Но ведь оператор сравнения там все равно должен быть определен, и компилятор должен об него споткнуться. Получается, vector компилируется не полностью весь сразу, а по частям? То есть, его оператор < не компилируется, если нигде не вызывается и поэтому в этом случае ошибок не возникает? Или это как-то по другому устроено? Сам я, ввиду скудных знаний С++, в страшных исходниках стандартной библиотеки пока не могу разобраться.
1 май 18, 15:38    [21381405]     Ответить | Цитировать Сообщить модератору
 Re: Компиляция шаблонов  [new]
Dimitry Sibiryakov
Member

Откуда:
Сообщений: 53394

Ржавый гвоздь
Получается, vector компилируется не полностью весь сразу, а по частям?

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

Posted via ActualForum NNTP Server 1.5

1 май 18, 15:54    [21381438]     Ответить | Цитировать Сообщить модератору
 Re: Компиляция шаблонов  [new]
Anatoly Moskovsky
Member

Откуда: Odessa
Сообщений: 6658
Ржавый гвоздь,

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

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

Соответственно оператор "<" для шаблона vector будет скомпилирован только если вы сравниваете вектора.
1 май 18, 16:01    [21381455]     Ответить | Цитировать Сообщить модератору
 Re: Компиляция шаблонов  [new]
a guest
Member

Откуда:
Сообщений: 335
Ржавый гвоздь, операторы сравнения для векторов — это отдельные шаблонные функции. Естественно, пока они не используются, то не инстанциируются.
1 май 18, 17:09    [21381590]     Ответить | Цитировать Сообщить модератору
 Re: Компиляция шаблонов  [new]
a guest
Member

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

Это называется SFINAE.
SFINAE называется не это.
1 май 18, 17:09    [21381592]     Ответить | Цитировать Сообщить модератору
 Re: Компиляция шаблонов  [new]
Anatoly Moskovsky
Member

Откуда: Odessa
Сообщений: 6658
a guest
Ржавый гвоздь, операторы сравнения для векторов — это отдельные шаблонные функции. Естественно, пока они не используются, то не инстанциируются.

Да, но ошибки нет не потому что они отдельные :)
a guest
SFINAE называется не это.

Ну, да, SFINAE не совсем то же самое. Но непосредственно связанное свойство.
1 май 18, 17:31    [21381643]     Ответить | Цитировать Сообщить модератору
 Re: Компиляция шаблонов  [new]
Ржавый гвоздь
Member

Откуда:
Сообщений: 137
Anatoly Moskovsky
Да, но ошибки нет не потому что они отдельные :)

То есть, получается, компилируются только те функции шаблонного класса, которые где-либо вызываются?
1 май 18, 18:34    [21381751]     Ответить | Цитировать Сообщить модератору
 Re: Компиляция шаблонов  [new]
Anatoly Moskovsky
Member

Откуда: Odessa
Сообщений: 6658
Ржавый гвоздь
То есть, получается, компилируются только те функции шаблонного класса, которые где-либо вызываются?

Да.
1 май 18, 18:49    [21381765]     Ответить | Цитировать Сообщить модератору
 Re: Компиляция шаблонов  [new]
MasterZiv
Member

Откуда: Питер
Сообщений: 34697
Ржавый гвоздь
Anatoly Moskovsky
Да, но ошибки нет не потому что они отдельные :)

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


Да, но грядут перемены и возможно после 20го года всё будет не так. (модули)
3 май 18, 10:11    [21383537]     Ответить | Цитировать Сообщить модератору
 Re: Компиляция шаблонов  [new]
Anatoly Moskovsky
Member

Откуда: Odessa
Сообщений: 6658
MasterZiv
Да, но грядут перемены и возможно после 20го года всё будет не так. (модули)

Модуль это всего лишь синтаксическое дерево куска кода без семантического разбора тех частей которые зависят от типа шаблона.
Они не заставляют инстанцировать весь этот код - компилятор сам будет выбирать из модуля что инстанцировать.
Поэтому с модулями будет то же самое.
3 май 18, 10:51    [21383704]     Ответить | Цитировать Сообщить модератору
 Re: Компиляция шаблонов  [new]
MasterZiv
Member

Откуда: Питер
Сообщений: 34697
Anatoly Moskovsky
MasterZiv
Да, но грядут перемены и возможно после 20го года всё будет не так. (модули)

Модуль это всего лишь синтаксическое дерево куска кода без семантического разбора тех частей которые зависят от типа шаблона.
Они не заставляют инстанцировать весь этот код - компилятор сам будет выбирать из модуля что инстанцировать.
Поэтому с модулями будет то же самое.


Руку дашь на отсечение ? (можно также дать что-то другое...)
3 май 18, 13:32    [21384257]     Ответить | Цитировать Сообщить модератору
 Re: Компиляция шаблонов  [new]
a guest
Member

Откуда:
Сообщений: 335
Anatoly Moskovsky
a guest
SFINAE называется не это.

Ну, да, SFINAE не совсем то же самое. Но непосредственно связанное свойство.
РАЗ ТУТ ТЕМКА ПРО ШАБЛОНЫ И SFINAE ЭТО ТИПА ПРО ШАБЛОНЫ ТОГДА ЗНАЧИТ НЕПОСРЕДСТВЕННО СВЯЗАННОЕ.

+
Откуда substitution failure, если вообще никакого substitution никуда не происходит???
3 май 18, 16:01    [21385035]     Ответить | Цитировать Сообщить модератору
 Re: Компиляция шаблонов  [new]
MasterZiv
Member

Откуда: Питер
Сообщений: 34697
Откуда substitution failure, если вообще никакого substitution никуда не происходит???

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

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

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

Сообщение было отредактировано: 4 май 18, 14:23
4 май 18, 14:22    [21387474]     Ответить | Цитировать Сообщить модератору
 Re: Компиляция шаблонов  [new]
a guest
Member

Откуда:
Сообщений: 335
MasterZiv
SFINAE это о другом вообще.
Я это и пытался донести.
4 май 18, 15:24    [21387770]     Ответить | Цитировать Сообщить модератору
 Re: Компиляция шаблонов  [new]
Anatoly Moskovsky
Member

Откуда: Odessa
Сообщений: 6658
SFINAE возможно потому, что возможно не делать подстановку реально неиспользованых функций.
4 май 18, 16:01    [21387922]     Ответить | Цитировать Сообщить модератору
Между сообщениями интервал более 1 года.
 Re: Компиляция шаблонов  [new]
tchingiz
Member

Откуда:
Сообщений: 39027
сколько функций для шаблона сгенерирует компилятор?
одну на все приложение или по одной в каждом скомпилированном файле?

1.h:
template <class T> void swap1(T& l, T& r) {
  T t;
  t = l;
  l = r;
  r = t;
}
extern int f();


a.cpp:
#include "1.h"

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


b.cpp:
#include "1.h"

int main() {
   int a = 1, b = 2; 
   swap1(a, b);
   f();
   return 0;
}
28 апр 21, 11:05    [22315485]     Ответить | Цитировать Сообщить модератору
 Re: Компиляция шаблонов  [new]
a guest
Member

Откуда:
Сообщений: 335
tchingiz, про взаимодействие инстанциации шаблонов функций с ODR ответа, похоже, нет.
28 апр 21, 11:54    [22315525]     Ответить | Цитировать Сообщить модератору
 Re: Компиляция шаблонов  [new]
Anatoly Moskovsky
Member

Откуда: Odessa
Сообщений: 6658
tchingiz
сколько функций для шаблона сгенерирует компилятор?
одну на все приложение или по одной в каждом скомпилированном файле?

При компиляции будет сгенерирована по копии функции в каждой единице трансляции.
Далее компилятор проведет инлайнинг если посчитает нужным.
Для копий которые не заинлайнены, при линковке произойдет случайный выбор одной из них и останется только она.
Код же заинлайненых функций так и останется продублированным в каждом месте вызова. Что в принципе и ожидаемо.
28 апр 21, 21:13    [22315970]     Ответить | Цитировать Сообщить модератору
 Re: Компиляция шаблонов  [new]
MasterZiv
Member

Откуда: Питер
Сообщений: 34697
Ржавый гвоздь
Знатоки С++, снова обращаюсь к вам за помощью. Пока только начинаю знакомиться с шаблонами, так что возник такой вопрос, буду благодарен, если кто на пальцах объяснит, как это работает.


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

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

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

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


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

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

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


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

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

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


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

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

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

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


Да, именно так.
29 апр 21, 00:10    [22316047]     Ответить | Цитировать Сообщить модератору
 Re: Компиляция шаблонов  [new]
Barlone
Member

Откуда:
Сообщений: 1454
Ну так то операции сравнения для вектора есть. https://en.cppreference.com/w/cpp/container/vector/operator_cmp
29 апр 21, 05:07    [22316079]     Ответить | Цитировать Сообщить модератору
 Re: Компиляция шаблонов  [new]
Dima T
Member

Откуда:
Сообщений: 15795
Вы на даты смотрите. tchingiz зачем-то древнюю тему апнул с совсем другим вопросом.
29 апр 21, 07:11    [22316094]     Ответить | Цитировать Сообщить модератору
Все форумы / C++ Ответить