Template определение и реализация в разных юнитах.. проблема
От: Lenikur Россия  
Дата: 24.05.04 12:06
Оценка:
Привет!
Определил шаблон в .h, реализацию его в .cpp.
Компилируется все замечательно. А при линковке, в юните, где происходит инстанцирование, линковщик выкидывает unresolved external всех методов темплейла..
Я перенес всю реализацию в .h файл.. все заработало.. как это понимать?
Re: Template определение и реализация в разных юнитах.. проб
От: jazzer Россия Skype: enerjazzer
Дата: 24.05.04 12:11
Оценка: 1 (1)
Здравствуйте, Lenikur, Вы писали:

L>Привет!

L>Определил шаблон в .h, реализацию его в .cpp.
L>Компилируется все замечательно. А при линковке, в юните, где происходит инстанцирование, линковщик выкидывает unresolved external всех методов темплейла..
L>Я перенес всю реализацию в .h файл.. все заработало.. как это понимать?

таковы шаблоны в С++
реализация должна быть видна везде, где она используется, соответственно самое простое — поместить ее в h-файл.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re: Template определение и реализация в разных юнитах.. проб
От: Кодт Россия  
Дата: 24.05.04 12:14
Оценка: 1 (1)
Здравствуйте, Lenikur, Вы писали:

L>Определил шаблон в .h, реализацию его в .cpp.

L>Компилируется все замечательно. А при линковке, в юните, где происходит инстанцирование, линковщик выкидывает unresolved external всех методов темплейла..
L>Я перенес всю реализацию в .h файл.. все заработало.. как это понимать?

Правильно понимать

Поскольку .h — это всего лишь подстановочный файл, то без потери общности мы можем копипастнуть его содержимое повсеместно:
// template_definitions.cpp

template<class T>
class Foo
{
public:
  void bar();
};

// определения шаблонных функций аналогичны инлайнам
template<class T>
void Foo<T>::bar() { ...... }

// В этом месте ни одного воплощения шаблона нет,
// и компилятор ничего не родил.
// Он же не знает, что...

//////////////////////////////

// template_usage.cpp

// объявление означает, что "где-то" есть реализация
template<class T>
class Foo
{
public:
  void bar();
};

main()
{
  Foo<int> foo;
  foo.bar(); // а реализация-то где? йок.
}
Перекуём баги на фичи!
Re: Template определение и реализация в разных юнитах.. проб
От: Lorenzo_LAMAS  
Дата: 24.05.04 12:14
Оценка:
Нуу, если у тебя новый борландовский компилятор или comeau, то пиши, например, так
//header.h
export template<class T>
class A
{
public:
   void fun();
};

//impl.cpp
template<class T>
void A<T>::fun()
{
}


А если нет, то воспользуйся поиском. Тут такое часто спрашивают.
Of course, the code must be complete enough to compile and link.
Re[2]: Template определение и реализация в разных юнитах.. п
От: Lenikur Россия  
Дата: 24.05.04 12:51
Оценка:
Не, не новый.. Builder 5. Export пробовал, не помогло.
Всем спасибо, помогли.

Здравствуйте, Lorenzo_LAMAS, Вы писали:

L_L>Нуу, если у тебя новый борландовский компилятор или comeau, то пиши, например, так

L_L>
L_L>//header.h
L_L>export template<class T>
L_L>class A
L_L>{
L_L>public:
L_L>   void fun();
L_L>};

L_L>//impl.cpp
L_L>template<class T>
L_L>void A<T>::fun()
L_L>{
L_L>}
L_L>


L_L>А если нет, то воспользуйся поиском. Тут такое часто спрашивают.
Re[3]: Template определение и реализация в разных юнитах.. п
От: Lorenzo_LAMAS  
Дата: 24.05.04 12:59
Оценка: 1 (1)
Здравствуйте, Lenikur, Вы писали:

L>Не, не новый.. Builder 5. Export пробовал, не помогло.

L>Всем спасибо, помогли.

Ни в 5ом, ни в 6ом, ни в билдерХ компилятор (5.5, 5.6 и т.д.) экспорт не поддерживают. Только в 6ом просто распознается ключевое слово экспорт. А вот в Борланд С++ technical Preview новый компилятор и компоновщик. И экспорт поддерживается.
Of course, the code must be complete enough to compile and link.
Re: Template определение и реализация в разных юнитах.. проб
От: Димчанский Литва http://dimchansky.github.io/
Дата: 24.05.04 13:21
Оценка:
Попробуй сделать примерно так (пишу общую идею):

заголовочный файл:
// mytemplate.hpp
#ifndef MYTEMPLATE_HPP
#define MYTEMPLATE_HPP

template <typename T>
class MyClass
{
private:
  T m_value;
public:
  MyClass();
  MyClass(T value);
  virtual ~MyClass();

  T GetValue() const;
  void SetValue(T value);
};

#endif


реализация:
// mytemplatedef.hpp
#ifndef MYTEMPLATEDEF_HPP
#define MYTEMPLATEDEF_HPP

#include "mytemplate.hpp"

template <typename T>
MyClass<T>::MyClass(): m_value()
{}

template <typename T>
MyClass<T>::MyClass(T value): m_value(value)
{}

template <typename T>
MyClass<T>::~MyClass()
{}

template <typename T>
T MyClass<T>::GetValue() const
{
  return m_value;
}

template <typename T>
void MyClass<T>::SetValue(T value)
{
  m_value = value;
}

#endif


Потом, в программе везде, где используешь шаблонный класс делаешь include заголовочного файла:

#include "mytemplate.hpp"
#include <iostream>

int main{}
{
  MyClass<int> a;
  std::cout << a.GetValue() << std::endl;
  a.SetValue(10);
  std::cout << a.GetValue() << std::endl;

  MyClass<double> b;
  std::cout << b.GetValue() << std::endl;
  a.SetValue(15);
  std::cout << b.GetValue() << std::endl;
  ...
}


А теперь, чтобы всё работало и не было ошибок на линковке, делаешь файл:
// MyClass_inst.cpp
#include "mytemplatedef.hpp"

// инстанцируем то, что нам надо в проекте
template MyClass<int>;
template MyClass<double>;

и включаешь этот файл в проект. Это один из методов, если не хочешь всё пихать в один h-файл.
Re[2]: Template определение и реализация в разных юнитах.. п
От: Lenikur Россия  
Дата: 25.05.04 05:21
Оценка:
Здравствуйте, Димчанский, Вы писали:

Д>Попробуй сделать примерно так (пишу общую идею): ...


Д>и включаешь этот файл в проект. Это один из методов, если не хочешь всё пихать в один h-файл.


Выглядит сильно..
Боюсь только это добавит запутанности.. но спасибо конечно.
Честно говоря, я не знал, что инстанированный класс шаблона это новый тип.
Re[3]: Template определение и реализация в разных юнитах.. п
От: Димчанский Литва http://dimchansky.github.io/
Дата: 25.05.04 06:56
Оценка:
Здравствуйте, Lenikur, Вы писали:

L>Выглядит сильно..

L>Боюсь только это добавит запутанности.. но спасибо конечно.

Я читал, что подобный подход в больших проектах вроде как должен увеличить скорость компиляции по сравнению с тем, если всё юудет в одном h-файле. Так как в последнем случае в разных единицах трасляции ссылки на один и тот же MyClass<int> могут приводить к повторному инстанцированию шаблона с заданным аргументом шаблона. Вроде так.

L>Честно говоря, я не знал, что инстанированный класс шаблона это новый тип.


Если шаблонный класс — на самом деле целое семейство классов, то его инстанцирование просто выделяет из этого огромного множества какой-то один класс.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.