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

Использование шаблонов - C++

Восстановить пароль Регистрация
 
AnopT
0 / 0 / 0
Регистрация: 11.11.2012
Сообщений: 8
11.11.2012, 11:35     Использование шаблонов #1
Здравствуйте, пытаюсь набросать элементарный пример шаблона в Visual Studio 12 и получаю ошибку компилятора:

error LNK2001: неразрешенный внешний символ ""class Derive<double> __cdecl operator-(class Derive<double> const &,class Derive<double> const &)" (??G@YA?AV?$Derive@N@@ABV0@0@Z)"

код программы:
C++
1
2
3
4
5
6
7
8
9
10
11
12
#include <math.h>
#include <stdlib.h>
#include "test.h"
using namespace std;
 
void main()
{
    Derive<double> C1(1.0);
    Derive<double> C4(4.0);
    Derive<double> X;
    X = C1 - C4;
}
код файла test.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
ifndef DERIVE_H
#define DERIVE_H
 
#include <iostream>
#include <math.h>
using namespace std;
 
template <class T> class Derive
{
   private:
      // Поля данных
      T u, du;
 
      //Закрытый конструктор
      Derive(const T,const T);
 
   public:
      //Конструкторы
      Derive();
      Derive(const T);
      Derive(const Derive<T>&);
      friend Derive<T> operator - (const Derive<T>&, const Derive<T>&);
};
template <class T> Derive<T>::Derive() : u(T(0)),du(T(1)) {}
 
template <class T> Derive<T>::Derive(const T v) : u(v),du(T(0)) {}
 
template <class T> Derive<T>::Derive(const T v,const T dv) : u(v),du(dv) {}
 
template <class T> Derive<T>::Derive(const Derive<T> &r) : u(r.u),du(r.du) {}
 
template <class T> Derive<T> operator - (const Derive<T> &x,const Derive<T> &y)
{ return Derive<T>(x.u-y.u,x.du-y.du); }
#endif
Файл test.h добавлен в проект в раздел Header Files.
Собственно вопрос, что я делаю не так?
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
zss
Модератор
Эксперт С++
 Аватар для zss
5955 / 5560 / 1788
Регистрация: 18.12.2011
Сообщений: 14,209
Завершенные тесты: 1
11.11.2012, 11:42     Использование шаблонов #2
Сделайте operator- членом класса:
C++
1
2
template <class T> Derive<T> Derive<T>::operator-(const Derive<T> &y)
{ return Derive<T>(this->u-y.u,this->du-y.du); }
AnopT
0 / 0 / 0
Регистрация: 11.11.2012
Сообщений: 8
11.11.2012, 11:57  [ТС]     Использование шаблонов #3
"тупо" заменил свой метод "operator-" на Ваш.
Результат компиляции: error C2039: -: не является членом "Derive<T>"

Может ещё где-нибудь надо что-то указать?
Eugine
 Аватар для Eugine
3 / 3 / 0
Регистрация: 10.11.2012
Сообщений: 63
11.11.2012, 11:57     Использование шаблонов #4
Во-первых, функция main должна возвращать значение int.
Во-вторых, в .h файлах крайне не желательно использовать 'using namespace', т.к. ваш файл присоединяется к основному файлу препроцессором и могут возникнуть проблемы, если у вас найдется функция или класс, имя которых совпадают с именами, в вашем случае, в стандартной библиотеке.

По теме. Ошибку выдает линковщик (не может присоединить дрежественную функцию), рискну предположить, что в шаблонах их вообще нельзя использовать.
zss
Модератор
Эксперт С++
 Аватар для zss
5955 / 5560 / 1788
Регистрация: 18.12.2011
Сообщений: 14,209
Завершенные тесты: 1
11.11.2012, 12:02     Использование шаблонов #5
В описании класса у operator-(...) естественно тоже надо менять объявление:
C++
1
      Derive<T> operator - (const Derive<T>&);
AnopT
0 / 0 / 0
Регистрация: 11.11.2012
Сообщений: 8
11.11.2012, 12:31  [ТС]     Использование шаблонов #6
Спасибо, скомпилировалось. Теперь, чтобы проверить правильность результатов, неплохо было бы реализовать оператор вывода. Для этого я объявил оператор
C++
1
friend ostream& operator << (ostream&, const Derive<T>&);
который реализует следующее:
C++
1
2
template <class T> ostream& operator << (ostream &s,const Derive<T> &r)
{ return s << r.u;}
соответственно, к коду раздела main добавилась строка
C++
1
cout << X;
Компилятор вновь ругается: error LNK2001: неразрешенный внешний символ ""class std::basic_ostream<char,struct std::char_traits<char> > & __cdecl operator<<(class std::basic_ostream<char,struct std::char_traits<char> > &,class Derive<double> const &)" (??6@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@std@@AAV01@ABV?$Derive@N@@@Z)"

Подскажите,пожалуйста, чем лечить?
zss
Модератор
Эксперт С++
 Аватар для zss
5955 / 5560 / 1788
Регистрация: 18.12.2011
Сообщений: 14,209
Завершенные тесты: 1
11.11.2012, 12:47     Использование шаблонов #7
Похоже обычный friend метод через шаблоны не реализовать (его тоже тогда надо делать с собственным шаблоном)
Добавьте в шаблон методы getU(){return u;}
и выводите через них
cout<<X.getu()<<X.getdu();
AnopT
0 / 0 / 0
Регистрация: 11.11.2012
Сообщений: 8
11.11.2012, 12:58  [ТС]     Использование шаблонов #8
Да, спасибо, все заработало. Не могли бы Вы пояснить подробнее о том, как работает новый оператор разности? Для вычисления разности нам ведь требуется два аргумента. А в переписанной Вами версии задается только один операнд...
BumerangSP
 Аватар для BumerangSP
4283 / 1405 / 121
Регистрация: 16.12.2010
Сообщений: 2,941
Записей в блоге: 3
11.11.2012, 12:59     Использование шаблонов #9
AnopT, если Вы пытаетесь вынести реализацию шаблонов в отдельный файл, то у Вас ничего не выйдет. Реализацию нужно делать там, где было объявление.
Обычно везде так. Я с этим так и не справился.
Nick Alte
Эксперт С++
1590 / 982 / 115
Регистрация: 27.09.2009
Сообщений: 1,898
Завершенные тесты: 1
11.11.2012, 13:07     Использование шаблонов #10
Цитата Сообщение от zss Посмотреть сообщение
Похоже friend метод через шаблоны не реализовать.
Зачем же такой пессимизм? Всё нормально реализуется.
DiffEreD
 Аватар для DiffEreD
1420 / 757 / 95
Регистрация: 21.06.2011
Сообщений: 1,740
Записей в блоге: 2
11.11.2012, 13:20     Использование шаблонов #11
Nick Alte, а объяснить можете, зачем там в вашем коде в привате класса вот эта строчка:
C++
1
friend ostream& operator << <T> (ostream&, const Test<T>&);
Чета я такого еще не видел.
Nick Alte
Эксперт С++
1590 / 982 / 115
Регистрация: 27.09.2009
Сообщений: 1,898
Завершенные тесты: 1
11.11.2012, 13:58     Использование шаблонов #12
yuron_477, как раз затем, чтобы объявить этот оператор дружественным. Причём поскольку оператор шаблонный, то объявить другом не весь шаблон вообще, а реализацию для того же самого типа (то есть, operator << для Test<int> не будет другом классу Test<double>). Сам смысл примера как раз в реализации friend с использованием шаблонов, что этому оператору и удаётся продемонстрировать, извлекая приватные данные.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
11.11.2012, 14:50     Использование шаблонов
Еще ссылки по теме:

использование шаблонов C++
Использование функций-шаблонов C++
С++ использование шаблонов C++

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

Или воспользуйтесь поиском по форуму:
zss
Модератор
Эксперт С++
 Аватар для zss
5955 / 5560 / 1788
Регистрация: 18.12.2011
Сообщений: 14,209
Завершенные тесты: 1
11.11.2012, 14:50     Использование шаблонов #13
Цитата Сообщение от AnopT Посмотреть сообщение
Да, спасибо, все заработало. Не могли бы Вы пояснить подробнее о том, как работает новый оператор разности? Для вычисления разности нам ведь требуется два аргумента. А в переписанной Вами версии задается только один операнд...
Их два, первый операнд - это this (текущий объект, для которого вызван метод,
при использовании знака - он стоит слева от знака), второй - в списке параметров.
Yandex
Объявления
11.11.2012, 14:50     Использование шаблонов
Ответ Создать тему
Опции темы

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