Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.56/9: Рейтинг темы: голосов - 9, средняя оценка - 4.56
2549 / 1208 / 358
Регистрация: 30.11.2013
Сообщений: 3,826

Линковщик и шаблонная функция

23.07.2016, 02:26. Показов 2134. Ответов 27
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Добрый вечер,

почему если реализовать функцию в header'e и подключить её в разные модули - already defined, а если функция шаблонная - всё норм)
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
23.07.2016, 02:26
Ответы с готовыми решениями:

Шаблонная функция
Всем привет! Подскажите пожалуйста, почему не работает следующее объявление функции-шаблона? template <class T> class Base ...

Шаблонная функция
Нужно создать шаблонную функцию, в которой массив сортируется пузырьком, поиск максимального и минимального значения! Вот с поиском...

Шаблонная функция
Как "научить" шаблонную функцию отличать массив от контейнера, то есть если написать: template <class contains, class type> type...

27
Неэпический
 Аватар для Croessmah
18144 / 10728 / 2066
Регистрация: 27.09.2012
Сообщений: 27,026
Записей в блоге: 1
23.07.2016, 02:32
Цитата Сообщение от rikimaru2013 Посмотреть сообщение
а если функция шаблонная - всё норм
У них иммунитет ODR.
Из всех экземпляров будет выбран какой-то один.
Цитата Сообщение от rikimaru2013 Посмотреть сообщение
подключить её в разные модули - already defined
inline добавьте, у inline-функций тоже иммунитет к ODR
1
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
23.07.2016, 02:33
добрый.

потому что если бы для шаблонов такое не сделали,
ими бы невозможно было нормально пользоваться.
1
23.07.2016, 02:34  [ТС]

Не по теме:

Цитата Сообщение от Croessmah Посмотреть сообщение
У них иммунитет ODR.
Их в детстве хрестили в церкви по сравнению с обычными функциями что ли?) :victory:

0
Неэпический
 Аватар для Croessmah
18144 / 10728 / 2066
Регистрация: 27.09.2012
Сообщений: 27,026
Записей в блоге: 1
23.07.2016, 02:37
Лучший ответ Сообщение было отмечено rikimaru2013 как решение

Решение

Цитата Сообщение от rikimaru2013 Посмотреть сообщение
Их в детстве хрестили в церкви по сравнению с обычными функциями что ли?
Вы мне не верите?
Опять придется лезть в стандарт...
Держите:
If D is a template and is defined in more than one translation unit, then the preceding requirements shall apply both to names from the template’s enclosing scope used in the template definition (14.6.3), and also to dependent names at the point of instantiation (14.6.2). If the definitions of D satisfy all these requirements, then the behavior is as if there were a single definition of D. If the definitions of D do not satisfy these requirements, then the behavior is undefined.
1
90 / 88 / 33
Регистрация: 20.07.2016
Сообщений: 403
23.07.2016, 02:43
когда компилятор встречает определение шаблона, он не создает код. Код создается только при непосредственном использовании шаблона - создании какого-нибудь инстанса. То есть компилятор фактически игнорит шаблоны в хэдерах до их непосредственного использования, что и влияет на организацию исходного кода.
1
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
23.07.2016, 02:47
Цитата Сообщение от Croessmah Посмотреть сообщение
У них иммунитет ODR.
у них нет иммунитета ODR.

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

это кстати, можно организовать и для обычных функций.
нужно просто поставить соответствующий ключик линкеру.
для вижуал студии: /FORCE:MULTIPLE
2
Неэпический
 Аватар для Croessmah
18144 / 10728 / 2066
Регистрация: 27.09.2012
Сообщений: 27,026
Записей в блоге: 1
23.07.2016, 02:49
Цитата Сообщение от hoggy Посмотреть сообщение
у них нет иммунитета ODR.
ок. Иммунитет против нарушения ODR.
Так лучше?
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
23.07.2016, 02:50
Цитата Сообщение от JIawliet Посмотреть сообщение
То есть компилятор фактически игнорит шаблоны в хэдерах до их непосредственного использования
нет, не игнорит.
при двухфазном парсинге (gcc), он осуществляет общую проверку синтаксиса,
и уже на этом этапе строит абстрактное синтаксическое дерево.

при однофазном парсинге(cl),
он осуществляет синтаксическую проверку объявления,
не затрагивая определение.

но в обоих случаях компилятор не игнорирует шаблон.
0
90 / 88 / 33
Регистрация: 20.07.2016
Сообщений: 403
23.07.2016, 02:53
C++
1
2
3
4
5
6
7
// .h
#include <iostream>
#include <string>
 
template <typename T>
void do_thing (const T& t)
{ std::cout << "thing: " << t; }
C++
1
2
3
4
5
6
7
8
9
10
11
/.cpp
#include "Header.h"
#include "Header.h"
 
//=======================================================================
int main ()
{
    do_thing(3);
 
    return 0;
}
получаем: С2995 void do_thing(const T&): шаблон функции уже определен

Цитата Сообщение от hoggy Посмотреть сообщение
у них нет иммунитета ODR.
+


это что касается ODR... а когда шаблон в хэдере и разных модулях - компилятору по-барабану ибо он их игнорит до создания какого-либо инстанса..
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
23.07.2016, 02:53
Цитата Сообщение от Croessmah Посмотреть сообщение
Так лучше?
нет, не лучше.

вы не поняли.
ODR - это правило одного определения в рамках одной ед. трансляции.

шаблоны имеют иммунитет против множественного определения
в рамках нескольких ед. трансляции.

но в одной и той же они так же подчиняются ODR,
как и обычные функции.
1
Неэпический
 Аватар для Croessmah
18144 / 10728 / 2066
Регистрация: 27.09.2012
Сообщений: 27,026
Записей в блоге: 1
23.07.2016, 02:56
Цитата Сообщение от JIawliet Посмотреть сообщение
получаем: С2995 void do_thing(const T&): шаблон функции уже определен
include quards поставьте.
А вывернуть можно что угодно,
и в данном случае у Вас шаблон в одной
единице трансляции определяется два раза,
правило же гласит "is defined in more than one translation unit"
0
90 / 88 / 33
Регистрация: 20.07.2016
Сообщений: 403
23.07.2016, 03:00
hoggy, ну да, с проверкой синтаксиса я согласен, проверяет... но потом отдыхает до того момента как обнаружит непосредственно применения шаблона...

Добавлено через 3 минуты
Цитата Сообщение от Croessmah Посмотреть сообщение
в одной
единице трансляции определяется два раза
ну вы ж говорите у него иммунитет к ODR)
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
23.07.2016, 03:02
Цитата Сообщение от JIawliet Посмотреть сообщение
компилятору по-барабану ибо он их игнорит до создания какого-либо инстанса
ничего он не игнорит.
не болтайте ерунды:

Почему компилируется не объявленная переменная в шаблоне?
Почему компилируется не объявленная переменная в шаблоне?
0
Неэпический
 Аватар для Croessmah
18144 / 10728 / 2066
Регистрация: 27.09.2012
Сообщений: 27,026
Записей в блоге: 1
23.07.2016, 03:06
Цитата Сообщение от hoggy Посмотреть сообщение
ODR - это правило одного определения в рамках одной ед. трансляции.
Значит я чего-то перемудрил

Добавлено через 2 минуты
Цитата Сообщение от JIawliet Посмотреть сообщение
ну вы ж говорите у него иммунитет к ODR)
Я имел ввиду приведенное правило, которое дано шаблончикам.
0
90 / 88 / 33
Регистрация: 20.07.2016
Сообщений: 403
23.07.2016, 03:13
Цитата Сообщение от hoggy Посмотреть сообщение
ничего он не игнорит.
не болтайте ерунды:
ок, что мы имеем - gcc не игнорит из-за two-phase name lookup... ок, это не отменяет того факта что в VS компилятору все равно до инстанцирования... это получается уже зависит от реализации компилятора... так что это:
Цитата Сообщение от hoggy Посмотреть сообщение
не болтайте ерунды
обидно было знаете ли
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
23.07.2016, 03:27
Цитата Сообщение от JIawliet Посмотреть сообщение
это не отменяет того факта что в VS компилятору все равно до инстанцирования
ещё раз вам повторяю: не все равно.

в следующем примере шаблон вообще так и не был инстанцирован:
C++
1
2
3
4
5
6
7
8
9
10
#include <iostream>
 
 
template<class T> void foo(){}
template<class T> void foo(){}
 
int main()
{
    std::cout << "Hello, world!\n";
}
выхлоп cl:
source_file.cpp(7): error C2995: 'void foo(void)': function template has already been defined
source_file.cpp(6): note: see declaration of 'foo'
0
90 / 88 / 33
Регистрация: 20.07.2016
Сообщений: 403
23.07.2016, 10:54
hoggy,
хорошо, вы меня убедили... значит дядя Липпман не прав (стр 827), ну или переводчик криво перевел... как теперь дальше жить? везде обман!

Добавлено через 7 часов 19 минут
hoggy, ок, что скажете на это?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
template <typename T>
class A
{
    A a;
};
 
template <typename T>
void func (T)
{ A<int> a; }
 
//=======================================================================
int main ()
{
    //A<int> a;
    //func ("text");
 
    return 0;
}
компилируется и в gcc, и в cl (раскомментируем любую из 2 строк - получаем error)... из этого выходит что компилятор игнорит тело функции, а в приведенном вами примере компилятор обращает внимание только на заголовки!
0
Игогошка!
 Аватар для ct0r
1801 / 708 / 44
Регистрация: 19.08.2012
Сообщений: 1,367
23.07.2016, 12:00
hoggy сказал ересь
ODR - это правило одного определения в рамках одной ед. трансляции.
, но все равно все повелись Респект))
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
23.07.2016, 16:07
Цитата Сообщение от ct0r Посмотреть сообщение
но все равно все повелись Респект))
см #5

Добавлено через 1 минуту
Цитата Сообщение от JIawliet Посмотреть сообщение
из этого выходит что компилятор игнорит тело функции, а в приведенном вами примере компилятор обращает внимание только на заголовки!
см #9
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
23.07.2016, 16:07
Помогаю со студенческими работами здесь

Шаблонная функция
Необходимо сделать шаблонную функцию, в которой x заменяется на y, а y заменяется на x: void f(int *x, float *y) Помогите...

Шаблонная функция С++
Помогите пожалуйсто понять ошибку Используется шаблонная функция в первом вызове она отображает значение типа int во втором типа double...

Шаблонная функция
Всем привет. Пытаюсь реализовать простенький парсер. Суть в том, что у меня есть ini файл с различными параметрами. Я все секции с...

Шаблонная функция
Дорогие форумчане, нуждаюсь в вашей помощи: имеется несколько функций, с большим объемом кода. Чтоб не повторять код для функций с другим...

Шаблонная функция
Помогите понять почему когда вызываешь функцию уже для конкретного типа (int,char*,double и т.п.)выдает ошибку: Error C2440 'type cast':...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка. Рецензия / Мнение/ Перевод https:/ / **********/ gallery/ thinkpad-x220-tablet-porn-gzoEAjs . . .
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru