Модераторы: bsa

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Инклюзивная модель компиляции шаблона, как её реализовать? 
V
    Опции темы
zim22
Дата 30.3.2009, 10:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


depict1
****


Профиль
Группа: Завсегдатай
Сообщений: 2682
Регистрация: 15.1.2009
Где: Украина

Репутация: 29
Всего: 69



Как правильно компилить шаблоны? Нужно ли в h-файл инклудить cpp файл в конце?
Компилятор ругается: foo.cpp(2) : error C2143: syntax error : missing ';' before '<'

Foo.h
Код
#ifndef FOO_H
#define FOO_H

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

#include "Foo.cpp"

#endif // FOO_H


Foo.cpp
Код
template <typename T>
void Foo<T>::do_smth() {
  // ...
}


main.cpp
Код
#include "Foo.h"

int main()
{
  Foo<int> f;
    return 0;
}



Это сообщение отредактировал(а) zim22 - 30.3.2009, 10:33


--------------------
PM MAIL   Вверх
Lazin
Дата 30.3.2009, 10:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

Репутация: 27
Всего: 154



Цитата(zim22 @  30.3.2009,  10:33 Найти цитируемый пост)
#include "Foo.cpp"

ну и напишут-же...
Цитата(zim22 @  30.3.2009,  10:33 Найти цитируемый пост)
foo.cpp(2) : error C2143: syntax error : missing ';' before '<'

ну еще-бы, откуда он узнает о существовании класса Foo?

Добавлено через 57 секунд
напиши все в заголовочном файле, и будет тебе счастье...
PM MAIL Skype GTalk   Вверх
IKM2007
Дата 30.3.2009, 10:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Зима близко
**


Профиль
Группа: Участник
Сообщений: 702
Регистрация: 26.4.2008
Где: olmedreca

Репутация: 3
Всего: 40



Шаблоны нужно реализовать в одном файле. Напиши все в файле .h.


--------------------
"К чёрту обстоятельства, я создаю возможности."
Брюс Ли
PM MAIL Skype   Вверх
zim22
Дата 30.3.2009, 10:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


depict1
****


Профиль
Группа: Завсегдатай
Сообщений: 2682
Регистрация: 15.1.2009
Где: Украина

Репутация: 29
Всего: 69



Цитата(Lazin @  30.3.2009,  10:36 Найти цитируемый пост)
ну и напишут-же...

Это пример с книжки "Язык программирования С++. Вводный курс. 4 издание." (Липпман, Лажойе, Му).
Так в ней учат программировать.

Вот текст:
В инклюзивной модели компиляции компилятору должны быть доступны определения всех используемых шаблонов. Как правило, чтобы сделать определения доступными, в файл заголовка, содержащий объявление шаблона функции или класса, добавляют директиву #include. Эта директива подключает файл(файлы) исходного кода, который содержит соответсвующие определения.

А вот приведённый исходный код:
// файл заголовка utilities.h
Код

#ifndef UTILITIES_H
#define UTILITIES_H

template <class T> int compare(const T&, const T&);
// другие объявления
#include "utilities.cc"

#endif


// реализация файла utilities.cc
Код

template <class T> int compare(const T &v1, const T &v2)
{
  if (v1 < v2 ) return -1;
  if (v2 < v1) return 1;
  return 0;
}

Так что, так делать не надо, как они "учат"? %)


--------------------
PM MAIL   Вверх
Lazin
Дата 30.3.2009, 10:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

Репутация: 27
Всего: 154



подключать в заголовочном файле, файл срр(сс) файл нельзя
в данном случае, пример из книги должен был выглядеть так:
Код

#ifndef UTILITIES_H
#define UTILITIES_H
template <class T> int compare(const T&, const T&);
// другие объявления
template <class T> int compare(const T &v1, const T &v2)
{
  if (v1 < v2 ) return -1;
  if (v2 < v1) return 1;
  return 0;
}
#endif

возможно, там имеется ввиду, что файл utilities.cc не является единицей трансляции, то-есть не компилируется компилятором, а просто служит для того, что-бы разделить реализацию и интерфейс шаблона
в этом случае, код из книги будет эквивалентен тому, что я написал smile 
PM MAIL Skype GTalk   Вверх
zim22
Дата 30.3.2009, 11:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


depict1
****


Профиль
Группа: Завсегдатай
Сообщений: 2682
Регистрация: 15.1.2009
Где: Украина

Репутация: 29
Всего: 69



Цитата(Lazin @  30.3.2009,  10:55 Найти цитируемый пост)
а просто служит для того, что-бы разделить реализацию и интерфейс шаблона

хорошо.  а чем мой пример плох? Я тоже хочу отделить реализацию шаблона от интерфейса. Поэтому и поступаю аналогично. Тоже cpp файл в конце инклудю smile



--------------------
PM MAIL   Вверх
Lazin
Дата 30.3.2009, 11:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

Репутация: 27
Всего: 154



Цитата(zim22 @  30.3.2009,  11:08 Найти цитируемый пост)
хорошо.  а чем мой пример плох? Я тоже хочу отделить реализацию шаблона от интерфейса. Поэтому и поступаю аналогично. Тоже cpp файл в конце инклудю

он плох тем, что так не делают, если хочешь, что-бы заработало, исключи из билда файл Foo.cpp
PM MAIL Skype GTalk   Вверх
p51x
Дата 30.3.2009, 11:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 14
Регистрация: 19.12.2008

Репутация: нет
Всего: нет



Цитата(zim22 @  30.3.2009,  11:08 Найти цитируемый пост)
а чем мой пример плох?

Цитата(Lazin @  30.3.2009,  10:55 Найти цитируемый пост)
файл utilities.cc не является единицей трансляции, то-есть не компилируется компилятором

У вас очевидно, что это не так... исключите его из компилируемых.
PM MAIL   Вверх
zim22
Дата 30.3.2009, 11:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


depict1
****


Профиль
Группа: Завсегдатай
Сообщений: 2682
Регистрация: 15.1.2009
Где: Украина

Репутация: 29
Всего: 69



А всё-таки, как разделить интерфейс шаблона от его реализации? Никак?
При создании своего класса(не шаблонного) я объявления в h файл кидаю, а реализацию в cpp.
*****
Я кажется понял. Можно в h-файле сначала объявить только методы. А уже в самом конце h-файла их определить smile

Это сообщение отредактировал(а) zim22 - 30.3.2009, 11:42


--------------------
PM MAIL   Вверх
baldina
Дата 30.3.2009, 12:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 15
Всего: 101



Цитата

Я кажется понял. Можно в h-файле сначала объявить только методы. А уже в самом конце h-файла их определить 


Ты правильно понял. smile
Есть еще одна возможность - принудительная генерация по шаблону. И вообще, учитывая, что для компиляции данного фрагмента кода не всегда обязательно иметь полное описание (например, если используется только указатель на переменную типа, достаточно объявить тип без подробностей), можно значительно уменьшить связи в программе.
Вот пример (немного искусственный, только для демонстрации технологии):

Код

// File min.h
// Forward declaration
template <typename T>
const T& min (const T& a, const T& b);

Код

// File min_imp.h
// Realization
template <typename T>
const T& min (const T& a, const T& b) 
{ return a < b ? a : b; }

Код

// File A.h
// Type A
struct A {
  A(int n) : a_(n) {}
  bool operator<(const A& o) const { 
    return a_< o.a_; 
  }
 private:
     int a_;
};

Код

// File a_imp.cpp
// Using definitions of A and min for code generation
#include “min_imp.h”

// опережающее объявление A, без подробностей
class A;
// Принудительная генерация min<A>()
template 
const A& min (const A& a, const A& b);

Код

// File f.cpp
// собираем всё вместе. здесь нет определения шаблона, только объявление
#include “a.h”
#include “min.h”

A f() {
  A a1(1), a2(2);
  return min(a1,a2);
}


PM MAIL   Вверх
zim22
Дата 30.3.2009, 13:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


depict1
****


Профиль
Группа: Завсегдатай
Сообщений: 2682
Регистрация: 15.1.2009
Где: Украина

Репутация: 29
Всего: 69



baldina, я не понимаю, как оно работает.
Вот у меня главный файл например:
Код
#include "A.h"
#include "my_min.h"

A my_func() {
  A a1(1), a2(2);
  return my_min(a1, a2);
}

int main()
{
  A res = my_func();
  return 0;
}


Вместо #include подключим содержимое соответствующих файлов, чтобы наглядней было:
Код
// File f.cpp
// собираем всё вместе. здесь нет определения шаблона, только объявление
//#include "A.h"
struct A {
  A(int n) : a_(n) { }
  bool operator<(const A& o) const { 
    return a_< o.a_; 
  }
 private:
     int a_;
};

//#include "my_min.h"
template <typename T>
const T& my_min (const T& a, const T& b);

A my_func() {
  A a1(1), a2(2);
  return my_min(a1, a2);
}

int main()
{
  A res = my_func();
  return 0;
}


Как файл f.cpp компилится? Ведь в нём нет определения шаблона my_min.


--------------------
PM MAIL   Вверх
baldina
Дата 30.3.2009, 14:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 15
Всего: 101



Цитата

Как файл f.cpp компилится? 

точно так же, как и при вызове нешаблонных функций. создается внешняя ссылка, которая удовлетворяется в процессе линковки.
вот здесь 
Код

return my_min(a1, a2);

вызов функции my_min<A>(). Встраивания не происходит, но как вызов extern функции это вполне законно.

в том коде, что я написал есть ошибка: шаблону min() надо знать про оператор <
вот так:

Код

// File f.cpp
struct A {
  A(int n) : a_(n) {}
  int get () const { return a_; }
private:
  int a_;
};

bool operator<(const A& lhs, const A& rhs) 
{ 
    return lhs.get() < rhs.get(); 
}

template <typename T>
const T& min (const T& a, const T& b);

A my_func() {
  A a1(1), a2(2);
  return min(a1, a2);
}

int main()
{
  A res = my_func();
  return 0;
}


Код

// File min_imp.h
// Realization
template <typename T>
const T& min (const T& a, const T& b) 
{ return a < b ? a : b; }

// опережающее объявление A, без подробностей
struct A;
bool operator<(const A&,const A&);

// Принудительная генерация min<A>()
template 
const A& min (const A& a, const A& b);


PM MAIL   Вверх
zim22
Дата 30.3.2009, 15:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


depict1
****


Профиль
Группа: Завсегдатай
Сообщений: 2682
Регистрация: 15.1.2009
Где: Украина

Репутация: 29
Всего: 69



baldina, спасибо.


--------------------
PM MAIL   Вверх
unicuum
  Дата 28.11.2009, 05:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 830
Регистрация: 16.3.2005
Где: Рашка

Репутация: нет
Всего: 8



Цитата(Lazin @  30.3.2009,  10:55 Найти цитируемый пост)

Код

#ifndef UTILITIES_H
#define UTILITIES_H
template <class T> int compare(const T&, const T&);
// другие объявления
template <class T> int compare(const T &v1, const T &v2)
{
  if (v1 < v2 ) return -1;
  if (v2 < v1) return 1;
  return 0;
}
#endif

возможно, там имеется ввиду, что файл utilities.cc не является единицей трансляции, то-есть не компилируется компилятором, а просто служит для того, что-бы разделить реализацию и интерфейс шаблона

Хотелось бы уточнить некоторые моменты для начала.

Вот это получается объявление шаблона функции.
Код

template <class T> int compare(const T&, const T&);

А это по логике вещей определение шаблона функции.
Код

template <class T> int compare(const T &v1, const T &v2)
{
  if (v1 < v2 ) return -1;
  if (v2 < v1) return 1;
  return 0;
}

Логика проистекает из определения, шаблоны это функции или классы определяемые без явного указания одного или нескольких типов. В обычных функциях вроде так всё и устроено. Если неправильно мыслю поправьте.

Далее файлы со следующими расширениями (*.h, *.hpp, *.hxx, *.hh) - заголовочные: Как правило содержат объявления (прототипы).

А вот с таким расширением (*.cpp, *.cxx, *.cc) - единицы компиляции, в книге написано именно так, а не трансляции. Для каждой единицы компиляции компилируется в Windows *.obj, в Unix и MacOS X *.o файлы, которые затем компонуются. Заголовочные файлы объявляются вначале единиц компиляции для синтаксического анализа компилятору.

Вот теперь можно перейти к теме - "инклюзивная модель компиляции шаблона". Взять хотя бы примеры baldina, почему они написаны так, а не иначе?


--------------------
user posted image
обычный день на винграде
PM   Вверх
mes
Дата 28.11.2009, 12:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



Цитата(unicuum @  28.11.2009,  04:28 Найти цитируемый пост)
Вот теперь можно перейти к теме - "инклюзивная модель компиляции шаблона"

а Вам не кажется, что тема успела разрешиться до того как  Вы дали разрешение ее продолжать smile  smile  smile 


Цитата(unicuum @  28.11.2009,  04:28 Найти цитируемый пост)
Взять хотя бы примеры baldina, почему они написаны так, а не иначе? 

можно и по другому,  примеры показательные и в них авторы пытались донести суть какого либо момента, стараясь чтоб получилось наиболее понятно.
smile


Цитата(unicuum @  28.11.2009,  04:28 Найти цитируемый пост)
А вот с таким расширением (*.cpp, *.cxx, *.cc) - единицы компиляции, в книге написано именно так, а не трансляции. 

во первых не сами файлы, а их содержимое со всеми включениями.
во вторых в  книжках пишут по разному  
Цитата

Единица трансляции, определение      43

http://lib.mexmat.ru/books/31673/s2





--------------------
PM MAIL WWW   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.0628 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.