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

Как правильно воспользоваться шаблоном - C++

Восстановить пароль Регистрация
 
thick_int
Заблокирован
14.11.2011, 02:40     Как правильно воспользоваться шаблоном #1
Начал изучать C++
Вот есть два файла

1)

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include "stdafx.h"
#include <iostream>
 
 
 
template <typename T> extern void output1(T a);
 
int _tmain(int argc, _TCHAR* argv[])
{
    using namespace std;
    int a = 6;
    output1(a);
    return 0;
}
2

C++
1
2
3
4
5
6
7
#include "stdafx.h"
 
template <typename T> void output1(T a)
{
    using namespace std;
    cout << a;
}
При попытке их скомпилировать выдаетс сообщения:
Код
1 error LNK1120: 1 неразрешенных внешних элементов	c:\users\...\documents\visual studio 2010\Projects\ConsoleD\Debug\ConsoleD.exe
Ошибка	1	error LNK2019: ссылка на неразрешенный внешний символ "void __cdecl output1<int>(int)" (??$output1@H@@YAXH@Z) в функции _wmain	c:\Users\...\documents\visual studio 2010\Projects\ConsoleD\ConsoleD\ConsoleD.obj
Если же я переношу определение функции output1() в первый файл, тамгде функци main, то все работает в поряядке.
Далее, если не пользуюсьшаблонами, а просто для функции output1() заранее выбираю жестко фиксированный тип, то работает и тогда, когда определение этой функции находитс в одном файле, а объвление (прототип) в файле с функцией main.
Почему же с шаблонами не получается?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
14.11.2011, 02:40     Как правильно воспользоваться шаблоном
Посмотрите здесь:

Подскажите как воспользоваться функцией. C++
C++ Сортировка массива с шаблоном
какой функцией воспользоваться? C++
C++ подскажите как сделать чтобы программа работала и выводила информацию о рейсах которыми можно воспользоваться для прибытия в пункт назначения раньше з
C++ как сделать что бы после решения 1 примера пользевателю предлагало еще раз воспользоваться?
Как воспользоваться данной функцией для экспорта ? C++
Ошибка с шаблоном C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Chelioss
179 / 179 / 4
Регистрация: 08.01.2011
Сообщений: 1,131
14.11.2011, 02:42     Как правильно воспользоваться шаблоном #2
Уберите extern. Для функций это не надо. Не знаю в этом ли ошибка, но это точно не надо.
thick_int
Заблокирован
14.11.2011, 02:45  [ТС]     Как правильно воспользоваться шаблоном #3
Убрал, все то же самое.
Да оно и по другому быть не могло, потому как если убрать шаблоны и воспользоваться просто типом int, то все работает прекрасно с extern.
Chelioss
179 / 179 / 4
Регистрация: 08.01.2011
Сообщений: 1,131
14.11.2011, 02:56     Как правильно воспользоваться шаблоном #4
Цитата Сообщение от thick_int Посмотреть сообщение
_tmain
Попробуйте заменить на main

Добавлено через 5 минут
И уберите везде #include "stdafx.h"

Добавлено через 29 секунд
И еще уберите
Цитата Сообщение от thick_int Посмотреть сообщение
int argc, _TCHAR* argv[]
Сделайте список параметров пустым.
thick_int
Заблокирован
14.11.2011, 02:57  [ТС]     Как правильно воспользоваться шаблоном #5
Да уж пробовал и все то же самое
Хотя честно говоря, по здравому рассуждениюю, исходяя из того, что:
1) Все прекрасно работает, если используется не шаблон, а обычный тип
2) Все также прекрасно работает, если перенести определение в один файл с main (разместив, например это определение ниже по тексту, чем main)

дело тут абсолютно не в этом. Какая то мелочь должна быть, о которой я просто не знаю, котораяя не позволяет вот так просто разносить определения и объявлени по разным файлам, если используются шаблоны. Там же в сообщении линковщика и пишетс об этом.
Bers
Заблокирован
14.11.2011, 04:00     Как правильно воспользоваться шаблоном #6
Цитата Сообщение от thick_int Посмотреть сообщение
Вот есть два файла
1. У файлов есть расширения? Ну первый то понятно - точка входа в программу.
Второй файл, это что? спп? хэдер?

2. Экспорт шаблонов мега упоротая тема. Либо не поддерживается большинством компиляторов, либо начинаются всякие пляски с бубнами.

Поэтому, весь православный мир пишет и прототип и реализацию шаблона в файлах хэдерах.
И только если совсем все плохо, и надо обязательно спрятать реализацию шаблона - только тогда начинается тайное шаманство.
thick_int
Заблокирован
14.11.2011, 04:44  [ТС]     Как правильно воспользоваться шаблоном #7
А вот тут все и начинается. Во всяком случае, если нельзя воспользоватьс прототипом шаблона (кстати, а это действительно истина в абсолютной инстанции или нет?), то тогда как быть с теми случами, когда функции, генерируемые на их основе, нужны в двух частях.
Ведь насколько я понял, в C++ можно иметь только одно определение функции, а во всех умных (или не очень) книжках по C++ авторы тупо включают файл с определением шаблонных функций, когда хотят продемонстрировать тот или иной функционал.

Одним словом, хотелось бы узнать наверняка, действительно ли шаблоны иимеют такие ограничения. Конечно, в этом случае, смысла битьс башкой об стену не имеет.
Bers
Заблокирован
14.11.2011, 05:49     Как правильно воспользоваться шаблоном #8
Цитата Сообщение от thick_int Посмотреть сообщение
А вот тут все и начинается. Во всяком случае, если нельзя воспользоватьс прототипом шаблона (кстати, а это действительно истина в абсолютной инстанции или нет?)
Что значит "нельзя воспользоваться прототипом шаблона" ?
Вы чета как то не правильно меня поняли.

Цитата Сообщение от thick_int Посмотреть сообщение
то тогда как быть с теми случами, когда функции, генерируемые на их основе, нужны в двух частях.
Что значит "функция нужна в двух частях" ? Разрезать функцию на пополам? Вот эту часть туда, а эту сюда. Или как?


Сейчас включаю режим телепатии: вы наверное, имеете ввиду принцип раздельной компиляции.
Когда в хэдэрах только прототипы, а в спп - реализации?

Обычные функции действительно примерно так и разделяют.
Более того, если не разделить - могут вылезти ошибки аля "двойное определение".
Но шаблонов это не касается.

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

Это связанно с особенностями самих шаблонов - с временем их инстанцирования и все такое прочее.

Вообще в любой книжке по шаблонам эта тема хорошо раскрывается. Например "Шаблоны с++ Справочник разработчика" Николаи Джосаттис
thick_int
Заблокирован
14.11.2011, 06:14  [ТС]     Как правильно воспользоваться шаблоном #9
Ну на первое возражение отвечаю так:
Вот есть стандартная схема, если что-то определено где-то, то в другом месте (если оно не видно по умолчанию) достаточно объявить его, предварив ключевым словом extern (разумеется, убрав всякую инициализацию).

Ну а что касается второго возражения, то тут я имел в виду принцип: одно определение и сколько угодно обяъвлений.

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

Есть еще один подход через ключевое слово export, но к сожадению в VC++ 2010 оно не поддерживается, а я так понял - это фактически тот же extern, только со стороны определения.
LosAngeles
Заблокирован
14.11.2011, 06:28     Как правильно воспользоваться шаблоном #10
Цитата Сообщение от thick_int Посмотреть сообщение
А вот тут все и начинается. Во всяком случае, если нельзя воспользоватьс прототипом шаблона (кстати, а это действительно истина в абсолютной инстанции или нет?), то тогда как быть с теми случами, когда функции, генерируемые на их основе, нужны в двух частях.
Ведь насколько я понял, в C++ можно иметь только одно определение функции, а во всех умных (или не очень) книжках по C++ авторы тупо включают файл с определением шаблонных функций, когда хотят продемонстрировать тот или иной функционал.
Одним словом, хотелось бы узнать наверняка, действительно ли шаблоны иимеют такие ограничения. Конечно, в этом случае, смысла битьс башкой об стену не имеет.
то что ты описал называется one definition rule и действует и распространяется оно не только на шаблоны, решается с помощью стражей включения
Bers
Заблокирован
14.11.2011, 06:36     Как правильно воспользоваться шаблоном #11
Цитата Сообщение от thick_int Посмотреть сообщение
Вот есть стандартная схема, если что-то определено где-то, то в другом месте (если оно не видно по умолчанию) достаточно объявить его, предварив ключевым словом extern (разумеется, убрав всякую инициализацию).
Брррр.... Это не стандартная схема, а специфичная для специфичных ситуэйшин. В 90% случаев нафег не нужная.

Вот есть два файла:
MyFunc.h //здесь лежат прототипы функций/классов
MyFunc.cpp //здесь лежит реализация этих функций/классов

Все что нужно для счастья - что бы файл спп был включен в проект.
Дальше везде, где тебе понадобятся эти функции/классы просто инклюдишь myFunc.h и все. Дальше пользуешься.

Далее, шаблоны.
Есть у тебя тупо один файл: myTemplate.h //здесь лежат и прототипы и реализации шаблонных функций или классов.

Все, им спп не нужно. В своём проекте просто тупо инклюдишь хэдер myTemplate.h и пользуешься.
thick_int
Заблокирован
14.11.2011, 06:53  [ТС]     Как правильно воспользоваться шаблоном #12
Да все верно. Только что проверил и работает.
Bers
Заблокирован
14.11.2011, 06:54     Как правильно воспользоваться шаблоном #13
Цитата Сообщение от thick_int Посмотреть сообщение
Да все верно. Только что проверил и работает.
Не забудь про стражников.
thick_int
Заблокирован
14.11.2011, 07:20  [ТС]     Как правильно воспользоваться шаблоном #14
А зачем они в этом случае?
Как я понял, точно такая же схема с обычными функцими уже не сработает, есть они там или нет, поскольку все таки формально мы имеем два ОПРЕДЕЛЕНИЯ, а не обявления.
Но в случае шаблонов оказалось, что это работает, ну а в случае обычных функций вряд ли это будет работать.

P.S. То есть:
1) Я включил файл с шаблоном в файл с функцией main.
2) Cоздал еще один файл и включил в него файл с шаблоном. То есть это уже второе определение.
3) В этом фтором файле создал еще одну функцию, котора вызывает шаблонную функцию, а ее прототип с extern поместил в файл с функцией main, откуда успешно вызвал и шаблонную функцию и ту вторую функцию, которая сама вызывает шшаблонную.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
14.11.2011, 08:08     Как правильно воспользоваться шаблоном
Еще ссылки по теме:

Бинарное дерево с шаблоном C++
Как воспользоваться set_intersection для двух list<string> C++
Поиск по файле за шаблоном C++
C++ Работа со списком, шаблоном
C++ Как воспользоваться shared_ptr?

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

Или воспользуйтесь поиском по форуму:
Bers
Заблокирован
14.11.2011, 08:08     Как правильно воспользоваться шаблоном #15
Цитата Сообщение от thick_int Посмотреть сообщение
А зачем они в этом случае?
За бубликом. Гугли "раздельная компиляция с++", "много файловый проект с++", "стражники в хэдерах с++"

Цитата Сообщение от thick_int Посмотреть сообщение
3) В этом фтором файле создал еще одну функцию, котора вызывает шаблонную функцию, а ее прототип с extern поместил в файл с функцией main, откуда успешно вызвал и шаблонную функцию и ту вторую функцию, которая сама вызывает шшаблонную.
Не нужны в майне никакие прототипы ни с какими экстернами.

Экстерн придуман для специфических ситуаций. Тебе для того что бы пользоваться функцией в майне он нафег не упал.

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

Все прототипы в хэдэрах, в спп только реализация.

Закинь этот долбанный прототип в хэдэр (к тому же шаблону)
Поставь туда стажников.

Подключи в спп этот хэдер. И пользуйся на здоровье.
Yandex
Объявления
14.11.2011, 08:08     Как правильно воспользоваться шаблоном
Ответ Создать тему
Опции темы

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