Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.71/7: Рейтинг темы: голосов - 7, средняя оценка - 4.71
1 / 1 / 0
Регистрация: 20.05.2016
Сообщений: 47

Работа с шаблонами

14.10.2018, 12:06. Показов 1404. Ответов 14

Студворк — интернет-сервис помощи студентам
я создаю 3 файла:
template.hpp
C++
1
2
3
4
5
6
7
#ifndef VECTOR_H_
#define VECTOR_H_
namespace TT{
    template <typename T> void Swop (T&a, T&b);
    template <> void Swop (int&a, int &b);
}
#endif //VECTOR_H_
template.cpp
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
#include "template.hpp"
namespace TT{
    template <typename T> void Swop (T&a, T&b){
        T temp;
        temp=a;
        a=b;
        b=temp;
    }
    template <> void Swop (int&a, int &b){
        a=a+10;
        b=b+40;
    }
}
main.cpp
C++
1
2
3
4
5
6
7
8
9
#include <iostream>
#include "template.hpp"
using namespace TT;
int main(){
char a='e',b='a';
    Swop(a,b);
    std::cout<<a<<" "<<b;
    return 0;
}
Почему при компиляции я получаю сообщение: undefined reference to `void TT::Swop<char>(char&, char&)'
Почему он не определен? Я для этого шаблон и создал что бы он определил все сам.
Но что удивительно если я определение шаблона кину в main.cpp то шаблон работает четко.
Кстати если использовать вместо char int то код работать будет.
0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
14.10.2018, 12:06
Ответы с готовыми решениями:

Работа с шаблонами с++
Добрый вечер. Опять возник вопрос( Нужно создать шаблон списка. Для этого нужно создать структуру, где будут храниться указатели на...

Работа с шаблонами С++
Задача следующая: реализовать пирамидальную сортировку с итерфейсом таким - подаем класс итератор на наши данные и сласс сравнения в класс...

Работа с шаблонами
Доброго вечера! Сейчас решаю задачку на использование шаблонов, и вот с чем столкнулся: при вводе значений в массив, выдает ошибку (она на...

14
 Аватар для anapshy
531 / 272 / 220
Регистрация: 14.11.2016
Сообщений: 1,052
14.10.2018, 12:25
Объявление и определение шаблонов должно находиться в одной трансляции файла
Файл template.h:
C++
1
2
3
4
5
6
7
8
#ifndef VECTOR_H_
#define VECTOR_H_
namespace TT{
    template <typename T> void Swop (T&a, T&b);
    template <> void Swop (int&a, int &b);
}
#include "template.hpp" // препроцессор вставит код из template.hpp в template.h
#endif //VECTOR_H_
Файл template.hpp:
C++
1
2
3
4
5
6
7
8
9
10
11
12
namespace TT{
    template <typename T> void Swop (T&a, T&b){
        T temp;
        temp=a;
        a=b;
        b=temp;
    }
    template <> void Swop (int&a, int &b){
        a=a+10;
        b=b+40;
    }
}
C++
1
2
3
4
5
6
7
8
9
#include <iostream>
#include "template.h"
using namespace TT;
int main(){
char a='e',b='a';
    Swop(a,b);
    std::cout<<a<<" "<<b;
    return 0;
}
0
2784 / 1937 / 570
Регистрация: 05.06.2014
Сообщений: 5,602
14.10.2018, 12:25
Цитата Сообщение от IDis Посмотреть сообщение
Почему при компиляции я получаю сообщение: undefined reference to `void TT::Swop<char>(char&, char&)'
Потому что тело шаблона нельзя выносить в cpp.
0
1 / 1 / 0
Регистрация: 20.05.2016
Сообщений: 47
14.10.2018, 13:05  [ТС]
Я создал 3 файла:
template.hpp
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#ifndef TEMPLATE_HPP
#define TEMPLATE_HPP
namespace TT{
    template <typename T> void Swop (T&a, T&b){
        T temp;
        temp=a;
        a=b;
        b=temp;
    }
    template <> void Swop (int&a, int &b){
        a=a+10;
        b=b+40;
    }
}
template.cpp
C++
1
#include "template.hpp"
main.cpp
C++
1
2
3
4
5
6
7
8
9
10
#include <iostream>
#include "template.hpp"
 
using namespace TT;
int main(){
char a='e',b='a';
    Swop(a,b);
    std::cout<<a<<" "<<b;
    return 0;
}
Как при этом мне не получить ошибки: multiple definition of `void TT::Swop<int>(int&, int&)'
Получилось множественное определение.
Тот код что дал мне anapshy тоже выдает ошибку
0
 Аватар для anapshy
531 / 272 / 220
Регистрация: 14.11.2016
Сообщений: 1,052
14.10.2018, 14:03
Странно, что у меня работает, а у вас нет.

Цитата Сообщение от IDis Посмотреть сообщение
Как при этом мне не получить ошибки: multiple definition of `void TT::Swop<int>(int&, int&)'
Не разделять на файлы, вот и всё.
Где объявляется шаблон, там и определяется.
Никакого разделения на header и source файлы!

Правильное решение.
template.hpp:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#ifndef TEMPLATE_HPP
#define TEMPLATE_HPP
namespace TT{
    template <typename T> void Swop (T&a, T&b){
        T temp;
        temp=a;
        a=b;
        b=temp;
    }
    template <> void Swop (int&a, int &b){
        a=a+10;
        b=b+40;
    }
}
#endif
main.cpp:
C++
1
2
3
4
5
6
7
8
9
10
#include <iostream>
#include "template.hpp"
 
using namespace TT;
int main(){
char a='e',b='a';
    Swop(a,b);
    std::cout<<a<<" "<<b;
    return 0;
}
Добавлено через 8 минут
Шаблоны, разделение на несколько файлов
0
1 / 1 / 0
Регистрация: 20.05.2016
Сообщений: 47
14.10.2018, 14:09  [ТС]
anapshy Да, но обрати внимание, что происходит когда мы заголовочный файл подключаем дважды:
Происходит множественное определение.
Попробуй в свой код добавить файл c содержимым

some.c
C++
1
#include "template.hpp"
Вот попробуй... будет ошибка.
0
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,816
14.10.2018, 14:29
Лучший ответ Сообщение было отмечено IDis как решение

Решение

Цитата Сообщение от IDis Посмотреть сообщение
Как при этом мне не получить ошибки: multiple definition of `void TT::Swop<int>(int&, int&)'
Сделать ее inline. Или конкретно ее вынести в cpp - она-то ведь не шаблон.
1
Неэпический
 Аватар для Croessmah
18149 / 10731 / 2067
Регистрация: 27.09.2012
Сообщений: 27,035
Записей в блоге: 1
14.10.2018, 14:30
Не собирается проект с шаблонным классом: "undefined reference"
Хоть закрепляй эту тему в шапку
0
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,816
14.10.2018, 14:32
template.hpp
C++
1
2
3
4
5
6
7
8
9
10
11
12
#ifndef TEMPLATE_HPP
#define TEMPLATE_HPP
namespace TT{
    template <typename T> void Swop (T&a, T&b){
        T temp;
        temp=a;
        a=b;
        b=temp;
    }
    template <> void Swop (int&a, int &b);
}
#endif
template.cpp
C++
1
2
3
4
5
6
7
8
#include "template.hpp"
 
namespace TT{
    template <> void Swop (int&a, int &b){
        a=a+10;
        b=b+40;
    }
}
main.cpp
C++
1
2
3
4
5
6
7
8
9
10
#include <iostream>
#include "template.hpp"
 
using namespace TT;
int main(){
char a='e',b='a';
    Swop(a,b);
    std::cout<<a<<" "<<b;
    return 0;
}
0
1 / 1 / 0
Регистрация: 20.05.2016
Сообщений: 47
14.10.2018, 17:37  [ТС]
DrOffset спасибо за идею. Но всё-таки как можно определение template <> void Swop (int&a, int &b);
сунуть в заголовочный файл? что бы все определения были в одном месте.
а то мусор какой то получается одно тут, другое там
0
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,816
14.10.2018, 17:46
Цитата Сообщение от IDis Посмотреть сообщение
Но всё-таки как можно определение template <> void Swop (int&a, int &b);
Я ж вам написал как - оно должно быть inline.
0
1 / 1 / 0
Регистрация: 20.05.2016
Сообщений: 47
14.10.2018, 18:00  [ТС]
inline же это ведь не эффективно, зачем нам 100 копий?
0
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,816
14.10.2018, 18:04
Цитата Сообщение от IDis Посмотреть сообщение
зачем нам 100 копий?
Откуда вы это взяли?
Если функция не встроилась, то компилятор (точнее линковщик) точно так же оставляет единственное определение в программе, т.к. адрес функции с внешним связыванием должен быть один. А если она встроится, то никаких 100 копий тем более не будет.

Вы inline со static не перепутали?
0
1 / 1 / 0
Регистрация: 20.05.2016
Сообщений: 47
14.10.2018, 20:04  [ТС]
inline - компилятор встраивает в взамен каждого вызова функции соответствующий код. т.е. он везде засунет определение функции.
static - Он будет хранить значение даже при выходе из функции. Как статик может сделать 100 копий? Это же противоречит сущности статика.

Или я что то путаю?
0
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,816
14.10.2018, 20:52
Цитата Сообщение от IDis Посмотреть сообщение
inline - компилятор встраивает в взамен каждого вызова функции соответствующий код. т.е. он везде засунет определение функции.
Компилятору сейчас абсолютно не важно есть там inline или нет - он все равно встроит вашу функцию на 2 строки в код, если у него будет доступно ее определение. Точно также он может не встроить помеченную inline функцию, если это в данной ситуации нецелесообразно.
Нам от inline в данном случае нужно совсем другое его свойство. inline нужен, чтобы получить "расслабленные" правила для выполнения ODR - и избавиться от ошибки множественного определения при оставлении определения в заголовочном файле. Она как раз и решается тем, что такие лишние копии этой функции будут выброшены линкером. И никаких 100 копий не получится.
Если же вы не хотите, чтобы функция встраивалась в принципе - то тогда у вас только один выход, вынести ее в отдельную единицу трансляции, как я показывал выше.

Цитата Сообщение от IDis Посмотреть сообщение
static - Он будет хранить значение даже при выходе из функции.
static не к значениям (переменным), а к функциям. Это когда в каждой единице трансляции, куда включен заголовочный файл со static функцией, будет находится собственная копия этой функции. Вот тут да, действительно реально получить 100 копий, как вы выразились.
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
14.10.2018, 20:52
Помогаю со студенческими работами здесь

Работа с шаблонами. Типизация
Реализовать сортировку вставками (в порядке возрастания значений) для целочисленного массива arr размером n (n &lt; 15), элементы...

Работа с двунаправленным списком и с шаблонами в С++
Здравствуйте Поомогите решить такую задачу: &quot;Используя стандартную библиотеку шаблонов STL и класс list по работе с двунаправленным...

Работа с шаблонами, типизация: пузырьковая сортировка строки
Дан массив символов arr &quot;ишъыйкюявдрэсцтьпбёфщчеугнлмохазж&quot;. Необходимо отсортировать данный массив в алфавитном порядке следования...

Композиционная связь между шаблонами. работа дестракторов
Есть например такой проект. Вопросы в следующем. Как происходит процесс работы дестрактора между этими классами ? Правильно ли...

работа с шаблонами
Ребят может поможет кто-нибудь написать скриптик?)очень нужно, завтра сдавать) Для рекламного сайта издательства «Альфа» создайте...


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

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Новые блоги и статьи
Ритм жизни
kumehtar 27.02.2026
Иногда приходится жить в ритме, где дел становится всё больше, а вовлечения в происходящее — всё меньше. Плотный график не даёт вниманию закрепиться ни на одном событии. Утро начинается с быстрых,. . .
[В процессе разработки] SDL3 для Web (WebAssembly): Сборка библиотек SDL3 и Box2D из исходников с помощью CMake и Emscripten
8Observer8 27.02.2026
Недавно вышла версия 3. 4. 2 библиотеки SDL3. На странице официальной релиза доступны исходники, готовые DLL (для x86, x64, arm64), а также библиотеки для разработки под Android, MinGW и Visual Studio. . . .
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru