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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Явное воплощение шаблонной функции 
V
    Опции темы
Brodyaga
Дата 27.7.2009, 18:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Всей здравствуйте! Хочу сделать у класса одну шаблонную функцию. Делаю так

myclass.h

Код

class MyClass
{
public:
   MyClass();
   ~MyClass();

   template<class T>
   static T* MyFunc(T*);
};


myclass.cpp

Код

MyClass::MyClass()
{
}
MyClass::~MyClass()
{
}

template <class T>
T* MyClass::MyFunc(T* object)
{
 return null;
}


myclassinst.cpp

Код

/*Файл реализующий "модель явного воплощения" для организации кода с шаблонами*/
#include "StdAfx.h"

#include "myclass.cpp"

#include "ClassA.h"
#include "ClassB.h"

//Набор директив явного воплощения
template ClassA* MyClass::MyFunc<ClassA>(ClassA* object);
template ClassB* MyClass::MyFunc<ClassB>(ClassB* object);


На всё это дело студия ругается так:
Код

Error    113    error LNK2005: "public: __cdecl MyClass::MyClass(void)" (??0MyClass@@QAA@XZ) already defined in myclass.obj                файл - myclassinst.obj
Error    114    error LNK2005: "public: __cdecl MyClass::~MyClass(void)" (??1MyClass@@QAA@XZ) already defined in myclass.obj               файл - myclassinst.obj    

и т.д.

может кто подскажет, что я делаю неправильно?

P.S. MSVC 2005

Это сообщение отредактировал(а) Brodyaga - 27.7.2009, 18:46
PM MAIL   Вверх
triclosan
Дата 27.7.2009, 19:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



попробуй не разносить определение и реализацию в разные файлы
PM MAIL   Вверх
Brodyaga
Дата 27.7.2009, 19:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата

попробуй не разносить определение и реализацию в разные файлы

Пробовал уже.. так работает.. Но ведь явное воплощение и нужно для того, чтобы работало всё с разносом определения и реализации в разные файлы.
Поэтому мне интересно как всётаки так сделать!?
PM MAIL   Вверх
vinick
Дата 27.7.2009, 19:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(Brodyaga @  27.7.2009,  19:13 Найти цитируемый пост)
Пробовал уже.. так работает.. Но ведь явное воплощение и нужно для того, чтобы работало всё с разносом определения и реализации в разные файлы.
Поэтому мне интересно как всётаки так сделать!? 

Вынести реализацию шаблонов в cpp-файл так как ты хочешь можно только при помощи ключевого слова export, которое поддерживают только Comeu С++ и Borland C++, а сейчас эту фичу по-моему вобще исключили из стандарта языка.

Кстати, зачем понадобилось явное инстанцирование?  Я встречал его только в одном старом проекте, где древний gcc  не мог сам разобраться с шаблонами и ему приходилось помогать руками.
PM MAIL ICQ Jabber   Вверх
azesmcar
Дата 27.7.2009, 19:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


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

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



Цитата(Brodyaga @  27.7.2009,  19:13 Найти цитируемый пост)
Пробовал уже.. так работает.. Но ведь явное воплощение и нужно для того, чтобы работало всё с разносом определения и реализации в разные файлы.

Экспорт шаблонов 99% компиляторов не поддерживается, пиши реализацию в .h файле.

меня опередили

Это сообщение отредактировал(а) azesmcar - 27.7.2009, 19:51
PM   Вверх
Brodyaga
Дата 27.7.2009, 20:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата

Вынести реализацию шаблонов в cpp-файл так как ты хочешь можно только при помощи ключевого слова export, которое поддерживают только Comeu С++ и Borland C++, а сейчас эту фичу по-моему вобще исключили из стандарта языка.

Не только... Например если я объявляю весь класс шаблонным, а не только функцию, а в файле myclassinst.cpp делаю так:
Код

template MyClass<ClassA>;
template MyClass<ClassB>;

то всё ок!

Цитата

Кстати, зачем понадобилось явное инстанцирование?

Затем, чтобы линкер не ругался на пустые ссылки оставленные компилятором из-за того, что он не может произвести воплощение шаблона.

Цитата

Экспорт шаблонов 99% компиляторов не поддерживается, пиши реализацию в .h файле.

Ну студийным ведь поддерживается? значит им както можно сделать? Ведь если делать целый класс шаблонным, то работает же......
PM MAIL   Вверх
azesmcar
Дата 27.7.2009, 20:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


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

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



Цитата(Brodyaga @  27.7.2009,  20:29 Найти цитируемый пост)
Ну студийным ведь поддерживается? 

Нет, не поддерживается.

Цитата(Brodyaga @  27.7.2009,  20:29 Найти цитируемый пост)
Ведь если делать целый класс шаблонным, то работает же...... 

Нет, не будет работать, если у тебя что-то работает - покажи, найдем причину, сделаем так что перестанет работать smile 
PM   Вверх
UnrealMan
Дата 27.7.2009, 23:54 (ссылка) |    (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Эх, Brodyaga, не туда ты забрёл smile Тебя тут щас научат, что VC++ не умеет работать с явным инстанцированием и что явное инстанцирование - это вообще экспорт шаблонов smile Ты только слушай да рот пошире разевай. Посмотри лучше на текст ошибки - там же ясно сказано, что проблема с конструктором и деструктором, которые у тебя не шаблонные и не inline, но определяются сразу в двух cpp файлах.
PM MAIL   Вверх
Brodyaga
Дата 28.7.2009, 06:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата

Цитата

Ведь если делать целый класс шаблонным, то работает же...... 


Нет, не будет работать, если у тебя что-то работает - покажи


Нет, работает!

myclass.h
Код

template<class T>
class MyClass
{
public:
   MyClass();
   ~MyClass();

   static T* MyFunc(T*);
};


myclass.cpp
Код

template <class T>
MyClass<T>::MyClass()
{
}
template <class T>
MyClass<T>::~MyClass()
{
}
template <class T>
T* MyClass<T>::MyFunc(T* object)
{
 return null;
}


myclassinst.cpp
Код

/*Файл реализующий "модель явного воплощения" для организации кода с шаблонами*/
#include "StdAfx.h"
#include "myclass.cpp"
#include "ClassA.h"
#include "ClassB.h"

//Набор директив явного воплощения
template MyClass<ClassA>;
template MyClass<ClassB>;


вот так, РАБОТАЕТ!


Цитата

Эх, Brodyaga, не туда ты забрёл smile Тебя тут щас научат, что VC++ не умеет работать с явным инстанцированием и что явное инстанцирование - это вообще экспорт шаблонов smile Ты только слушай да рот пошире разевай.

да я пока ещё не вижу к чему можно прислушаться  smile

Цитата

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

Тоесть избежать этого можно только включив строки 
template ClassA* MyClass::MyFunc<ClassA>(ClassA* object);
template ClassB* MyClass::MyFunc<ClassB>(ClassB* object);
в myclass.cpp? Я кстати так тоже пробовал и так работает... но хотелось чтобы эти строки в отдельном файле находились... Значит вариант с отдельным файлом(myclassinst.cpp) для этих строк отпадает? только в myclass.cpp!?!?

Это сообщение отредактировал(а) Brodyaga - 28.7.2009, 06:55
PM MAIL   Вверх
azesmcar
Дата 28.7.2009, 06:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


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

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



UnrealMan

А причем тут явное инстанцирование? Человек писал что хочет реализовывать и определять в разных файлах, если он инстанцировать хочет, так значит термин не тот подобрал. Лично мне слово "воплощение шаблона" ничего не говорит smile Может твои догадки и вернее отражают суть.

Цитата(Brodyaga @  28.7.2009,  06:53 Найти цитируемый пост)
#include "myclass.cpp"

Конечно будет работать, какая разница включать cpp файл или header? В итоге это одно и тоже. Если в конечном итоге определение будет включено в cpp файл - будет работать, дели хоть на 100 файлов.
UnrealMan прав, тут экспортом шаблонов и не пахнет. Я код не смотрел, прочитал 
Цитата

чтобы работало всё с разносом определения и реализации в разные файлы

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

Добавлено @ 07:05
Brodyaga

А проблема в том, что ты делаешь include cpp файл и его же скорее всего компилируешь, получаеся два определения конструктора и деструктора, либо пиши все в хидер файле, либо убери свой cpp который инклудишь из проекта, чтоб не компилировался.

Это сообщение отредактировал(а) azesmcar - 28.7.2009, 07:09
PM   Вверх
Леопольд
Дата 28.7.2009, 08:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(azesmcar @ 28.7.2009,  06:56)
А проблема в том, что ты делаешь include cpp файл и его же скорее всего компилируешь, получаеся два определения конструктора и деструктора, либо пиши все в хидер файле...

А ещё лучше, разберись с линковкой С++. Тебе необходимо понимание как она работает.
Надо помнить несколько вещей: что такое "единица трансляции", он же "модуль". Каким образом линковщик работает с разными фукнциями/переменными (static, inline и обычные) когда код оных уже оттранслирован в (разные) модули. Всё это объединаяется под одним термином - "раздельная компиляция".

как правило, сколько файлов *.cpp столько и модулей *.obj, не следует делать #include <*.cpp>

Цитата(azesmcar @ 28.7.2009,  06:56)
либо убери свой cpp который инклудишь из проекта, чтоб не компилировался.

Либо переименуй его в *.h smile


Это сообщение отредактировал(а) Леопольд - 28.7.2009, 08:06


--------------------
вопросов больше чем ответов
PM MAIL   Вверх
Brodyaga
Дата 28.7.2009, 08:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата

Я код не смотрел,

А надо смотреть всё smile


Цитата

Цитата

чтобы работало всё с разносом определения и реализации в разные файлы


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

Я имел ввиду, что хочу чтобы явное воплощение(инстанцирование) работало и с разносом определения и реализации в разные файлы.. помоему всё было предельно ясно, если читать сначала... 

Цитата

как правило, сколько файлов *.cpp столько и модулей *.obj

это я знаю... 

Цитата

не следует делать #include <*.cpp>

при моём подходе именно cpp нужно инклудить

Цитата

либо убери свой cpp который инклудишь из проекта, чтоб не компилировался.


Цитата

Либо переименуй его в *.h smile


Чото мне это как то криво кажется... наверное лучше строки 
template ClassA* MyClass::MyFunc<ClassA>(ClassA* object);
template ClassB* MyClass::MyFunc<ClassB>(ClassB* object);
в myclass.cpp перенесу..


PM MAIL   Вверх
azesmcar
Дата 28.7.2009, 08:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


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

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



Цитата(Brodyaga @  28.7.2009,  08:36 Найти цитируемый пост)
А надо смотреть всё smile

Смотря что делаешь, я на конкретную фразу отвечал а не на вопрос. Код смотреть не было времени и причину ошибки я тоже не называл. То что ты хочешь реализуется методом экспорта шаблонов, а твоя реализация отличается от реализации в заголовочном файле лишь тем, что ты .h заменил на .cpp (по сути файл переименовал) и еще компилируешь его.

Цитата(Brodyaga @  28.7.2009,  08:36 Найти цитируемый пост)
при моём подходе именно cpp нужно инклудить

какая разница? что меняет расширение файла? Это условности.

Цитата(Brodyaga @  28.7.2009,  08:36 Найти цитируемый пост)
Чото мне это как то криво кажется... наверное лучше строки 

криво это инклудить cpp файл.

Избавь себя от проблем, пиши все в заголовочном файле. В этом ничего ненормального нет, посмотри как сделано в STL.

Это сообщение отредактировал(а) azesmcar - 28.7.2009, 08:46
PM   Вверх
Brodyaga
Дата 28.7.2009, 10:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата

Смотря что делаешь, я на конкретную фразу отвечал а не на вопрос.

А фраза вытекала из конкретного вопроса, поэтому иговорю что надо всё смотреть smile

Цитата


какая разница? что меняет расширение файла? Это условности.

криво это инклудить cpp файл.

Про расширение какого именно файла вы говорите поясняйте пожалуйста.

Цитата

какая разница? что меняет расширение файла? Это условности.

Такая, что если подключать myclass.h файл к файлу myclassinst.cpp, то явное воплощение шаблона не работает..
PM MAIL   Вверх
azesmcar
Дата 28.7.2009, 10:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


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

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



Цитата(Brodyaga @  28.7.2009,  10:26 Найти цитируемый пост)
А фраза вытекала из конкретного вопроса, поэтому иговорю что надо всё смотреть smile

Без разницы из чего она вытекает, фраза была полной и носила конкретный смысл. В правильно сформулированном виде эта фраза однозначна и не зависит от контекста.

Цитата(Brodyaga @  28.7.2009,  10:26 Найти цитируемый пост)
Про расширение какого именно файла вы говорите поясняйте пожалуйста.

про расширение cpp файла.

Цитата(Brodyaga @  28.7.2009,  10:26 Найти цитируемый пост)
Такая, что если подключать myclass.h файл к файлу myclassinst.cpp, то явное воплощение шаблона не работает.. 

Повторяюсь, CPP файл твой компилятор КОМПИЛИРУЕТ, потому при линковке у класса получается два конструктора
1 - в myclass.cpp
2 - в myclassinst.cpp
а .h файл компилятор игнорирует и не компилирует.
PM   Вверх
Страницы: (3) Все [1] 2 3 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

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

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


 




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


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

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