Форум программистов, компьютерный форум CyberForum.ru

Шаблон функционального класса - C++

Восстановить пароль Регистрация
 
serjflint
0 / 0 / 0
Регистрация: 23.09.2013
Сообщений: 6
27.10.2013, 11:43     Шаблон функционального класса #1
Пишу лабораторную на С++. Нужно написать шаблоны функциональных классов, с методами вне этих шаблонов, и всё это в отдельном СРР. Я написал:
main:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
#include <stdlib.h>
#include <ctime>
#include "Classes.h"
using namespace std;
 
int main()
{
int a[15], b = 15;
srand( time( NULL ) );
for(int i = 0; i < 15; i++)
a[i] = rand() % 100 + 1;
try
{
Print<int>()(a, b);
cout << Max<int>()(a, b) << endl;
}
catch(Exception ex)
{
cout << ex.Sender << " " << ex.Message << endl;
}
return 0;
}
Classes.cpp:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#include "Classes.h"
#include <iostream>
using namespace std;
 
template<class T>
bool Less<T>::operator () (const T& Left, const T& Right) const
{
return Left < Right;
}
 
template<class T, class Comparer>
T Min<T, Comparer>::operator() (const T mas[], int cnt) const
{
if(cnt <= 0)
throw Exception("Min", "Empty");
T a = mas[0];
for(int i = 0; i < cnt; i++)
if(Comparer()(mas[i], a))
a = mas[i];
return a;
}
 
template<class T, class Comparer>
T Max<T, Comparer>::operator() (const T mas[], int cnt) const
{
if(cnt <= 0)
throw Exception("Max", "Empty");
T a = mas[0];
for(int i = 0; i < cnt; i++)
if(Comparer()(a, mas[i]))
a = mas[i];
return a;
}
 
template<class T>
T Sum<T>::operator() (const T mas[], int cnt) const
{
if(cnt <= 0)
throw Exception("Sum", "Empty");
T a(0);
for(int i = 0; i < cnt; i++)
a += mas[i];
return a;
}
 
template<class T>
void Print<T>::operator ()(const T mas[], int cnt) const
{
if(cnt <= 0)
throw Exception("Print", "Empty");
for(int i = 0; i < cnt; i++)
cout << mas[i] << " ";
cout << endl;
}
Classes.h:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#pragma once
#include <cstring>
 
class Exception;
 
template <class T>
class Less
{
public:
bool operator () (const T& Left, const T& Right) const;
};
 
template <class T, class Comparer = Less<T> >
class Min
{
public:
T operator () (const T mas[], int cnt) const;
};
 
template <class T, class Comparer = Less<T> >
class Max
{
public:
T operator () (const T mas[], int cnt) const;
};
 
template <class T>
class Sum
{
public:
T operator () (const T mas[], int cnt) const;
};
 
template <class T>
class Print
{
public:
void operator () (const T mas[], int cnt) const;
};
 
class Exception
{
public:
char Sender[30];
char Message[100];
Exception(char* sndr, char* msg)
{
strcpy_s(Sender, sndr);
strcpy_s(Message, msg);
}
};
но компилятор жутко ругается:
Кликните здесь для просмотра всего текста
Ошибка 2 error LNK2019: ссылка на неразрешенный внешний символ "public: void __thiscall Print<int>::operator()(int const * const,int)const " (??R?$Print@H@@QBEXQBHH@Z) в функции _main C:\Users\Admin\documents\visual studio 2012\Projects\Win32Project1\Win32Project1\main.obj Win32Project1
Ошибка 3 error LNK2019: ссылка на неразрешенный внешний символ "public: int __thiscall Max<int,class Less<int> >::operator()(int const * const,int)const " (??R?$Max@HV?$Less@H@@@@QBEHQBHH@Z) в функции _main C:\Users\Admin\documents\visual studio 2012\Projects\Win32Project1\Win32Project1\main.obj Win32Project1
Ошибка 4 error LNK2019: ссылка на неразрешенный внешний символ _WinMain@16 в функции ___tmainCRTStartup C:\Users\Admin\documents\visual studio 2012\Projects\Win32Project1\Win32Project1\MSVCRTD.lib(crtexew.obj) Win32Project1

Плюс дело в том, что когда я пишу всё это в одном файле, с функциями внутри шаблонов всё прекрасно работает.
Если "подключить Classes.cpp(почему так не знаю)" в QT то всё тоже компилится и работает.
И кто-нибудь подскажите, как редактировать свои сообщения после того как на них кто-нибудь ответил.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
27.10.2013, 11:43     Шаблон функционального класса
Посмотрите здесь:

Шаблон класса. Ошибка `undefined reference` C++
Шаблон класса (параметризация класса) C++
C++ Шаблон класса
C++ Шаблон класса в качестве параметра другому шаблону
C++ шаблон класса
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
ct0r
C++/Haskell
 Аватар для ct0r
1549 / 568 / 39
Регистрация: 19.08.2012
Сообщений: 1,174
Завершенные тесты: 1
27.10.2013, 12:12     Шаблон функционального класса #2
Цитата Сообщение от serjflint Посмотреть сообщение
но компилятор жутко ругается
Плюс дело в том, что когда я пишу всё это в одном файле, с функциями внутри шаблонов всё прекрасно работает.
Если "подключить Classes.cpp(почему так не знаю)" в QT то всё тоже компилится и работает.
Объяснение ко всему тут одно. Оно заключается в том, почему линкер ругается.

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

Когда мы компилим main как единицу трансляции, у нас есть аргументы шаблонов, но нет их определения. Компилятор ставит заглушки и надеется, что линкер потом все сделает. Когда мы компилим Classes.cpp, у нас есть определения шаблонов, но мы без понятия, для каких аргументов их инстанцировать. Поэтому никакой реализации шаблонов мы так и не получаем. Линкер потом смотрит - вызовы определений есть, а самих определений нет. Непорядок.
serjflint
0 / 0 / 0
Регистрация: 23.09.2013
Сообщений: 6
27.10.2013, 14:45  [ТС]     Шаблон функционального класса #3
То есть в MVS нельзя методы шаблонных функциональных классов писать в другом срр?
ct0r
C++/Haskell
 Аватар для ct0r
1549 / 568 / 39
Регистрация: 19.08.2012
Сообщений: 1,174
Завершенные тесты: 1
27.10.2013, 14:50     Шаблон функционального класса #4
На данный момент, учитывая переносимость, можно выбирать между вариантами:
1) реализовывать шаблоны в том же хедере, где они объявлены
2) в конце хедера заинклюдить cpp-файл с реализацией, что по сути вариант 1
3) использовать явное инстанцирование (не рекомендую).
serjflint
0 / 0 / 0
Регистрация: 23.09.2013
Сообщений: 6
28.10.2013, 17:25  [ТС]     Шаблон функционального класса #5
Спасибо, что объяснили. Напишу всё в хедере.
Yandex
Объявления
28.10.2013, 17:25     Шаблон функционального класса
Ответ Создать тему
Опции темы

Текущее время: 18:50. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru