Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: template описание и определение  (Прочитано 9189 раз)
0 Пользователей и 9 Гостей смотрят эту тему.
asker
Помогающий

ru
Offline Offline
Пол: Мужской

« : 23-10-2005 05:47 » 

кто-нибудь сталкивался с такой проблемой
Пишу описание template в .h - файле
template <class Node> class CBTree {
...
int MethodA(int a);
};
Дальше в .cpp:
template<class Node> int  CBTree<Node>::MethodA(int a)
{
}
И потом где-то его вызываю...
Но линковщик не дает fatal error LNK2001...
Если сразу в .h-файле внутри шаблона пишу тело метода, то тогда все в порядке.Никто не знает почему и как с этом бороться.
Используемая среда (Visual C++)
Записан

С уважением, asker
ysv_
Помогающий

ua
Offline Offline

« Ответ #1 : 23-10-2005 11:03 » 

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

ru
Offline Offline
Пол: Мужской

« Ответ #2 : 23-10-2005 11:46 » 

Спасибо ysv_, я понял и про (декларацию и определение) и про глобальную функцию, которой хотел передать адрес public-метода, т.е. возможное решение второго вопроса - это сделать дружественную функцию Compare для класса A. А вот про функторы я понял не совсем, т.е. для класса A я должен написать что-то вроде:
A operator() { return *this; }
Или ты имел в виду переопределить конкретные операотры сравнения, т.е. что-то вроде:
A operator<(A &a) {
...
}
Записан

С уважением, asker
asker
Помогающий

ru
Offline Offline
Пол: Мужской

« Ответ #3 : 23-10-2005 11:54 » 

Это связано с тем, что использование линковщика для темплейтного кода не возможно (в большинстве компиляторов на сегодняшний день).
А почему, какая разница когда я использую template. В том же cpp где он описан или в другом?
Записан

С уважением, asker
ysv_
Помогающий

ua
Offline Offline

« Ответ #4 : 23-10-2005 15:22 » 

Темплейтный код нельзя непосредственно преобразовать в объектный. В объектный код преобразуются реализация темплейтного кода для указаных при реализации типов. В точке реализации должен быть доступен весь темплейтный код подлежащий реализации.
Например:
template <class Node> class CBTree {
...
int MethodA(int a);
};
template<class Node> int CBTree<Node>::MethodA(int a)
{
}
В момент вызова CBTree<ConcreteNode>::Method(5) - весь код template<class Node> int CBTree<Node>::MethodA(int a) должен быть доступен. И вот на на основании темплейтного кода, после подстановки конкретного параметра (в моем примере ConcreteNode) возможна генерация объектного кода.


Записан
ysv_
Помогающий

ua
Offline Offline

« Ответ #5 : 23-10-2005 15:59 » 

Насчет функторов имелось ввиду, что если template<class T> void QSort(T *buf,int num,int (*Compare)(T arg1,T arg2));
переписать как template<class T, class Compare> void QSort(T *buf,int num, Compare& compare);
(скорее всего, в функции QSort других изменений не потребуется),

то в качестве compare можно использовать как отдельную функцию, так и функтор, который в твоем случае мог бы быть:
class B {
...
   A* m_arrayA;
   int m_num;
public:
  int operator()(A &a1, A &a2);
   void Method();
};

а сам вызов:
void B::Method() {
    ...
   QSort<A>(m_arrayA, m_num, *this);    ...
}

Вот полностью рабочий пример:
template <class C> int find_2(C& c)
{
  return c(1, 2);
}

int add_2(int a, int b)
{
  return a+b;
}

class A
{
public:
  int operator()(int a1, int a2)
  {
    return a1+a2;
  }

  void b()
  {
    find_2(*this);
  }
} a;

int main()
{
    int a1=find_2(add_2);
    int a2=a.b();
}
Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines