![]() |
|
Модераторы: bsa |
![]()
|
|
| pr5erg1y |
|
||||||
|
Новичок Профиль Группа: Участник Сообщений: 1 Регистрация: 3.3.2012 Репутация: нет Всего: нет |
Первое:
Вот перегружонный инкремент. Пробовал сделать декремент - не получилось. Подскажите как!
Второе: Вот перегружонные cin и cout:
Все работает нормально. Делаю через шаблоны:
Выводит ошыбки: 1) warning LNK4042: объект указан более одного раза; лишние не учитываются 2) error LNK2019: ссылка на неразрешенный внешний символ "class std::basic_ostream<char,struct std::char_traits<char> > & __cdecl operator<<(class std::basic_ostream<char,struct std::char_traits<char> > &,class CVector<double> const &)" (??6@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@std@@AAV01@ABV?$CVector@N@@@Z) в функции _main 3) error LNK2019: ссылка на неразрешенный внешний символ "class std::basic_istream<char,struct std::char_traits<char> > & __cdecl operator>>(class std::basic_istream<char,struct std::char_traits<char> > &,class CVector<double> &)" (??5@YAAAV?$basic_istream@DU?$char_traits@D@std@@@std@@AAV01@AAV?$CVector@N@@@Z) в функции _main 4) fatal error LNK1120: 2 неразрешенных внешних элементов Что я делаю не так? Жду помощи. |
||||||
|
|||||||
| bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 85 Всего: 196 |
реализация шаблонов должна быть ВО ВСЕХ ЕДИНИЦАХ КОМПИЛЯЦИИ, другими словами - в хидере. А ты, скорее всего, разместил в *.cpp.
Кстати, когда возникнут ошибки после переноса, воспользуйся ключевым словом inline. |
|||
|
||||
| Fynivx |
|
||||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 72 Регистрация: 13.8.2011 Репутация: нет Всего: 1 |
В заголовке:
В коде класса:
И так далее по аналогии. Это должно избавить от ошибок линковки. Но вряд ли избавит от первого варнинга. В чем там проблема - я не знаю. Но, скорее всего, что-то просто описано дважды. |
||||
|
|||||
| bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 85 Всего: 196 |
Fynivx, так делать не надо, если ты не знаешь, зачем нужна такая возможность.
|
|||
|
||||
| Fynivx |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 72 Регистрация: 13.8.2011 Репутация: нет Всего: 1 |
bsa, инстанцинирование делает экземпляр шаблона для указанного класса. Это для того, чтобы избежать дублирования одного и того же кода, что получится, если, при полном описании в заголовке, в разных исходниках использовать шаблон с одним и тем же типом.
Необходимо для описания шаблонов в библиотеках - там есть острая необходимость создать экземпляры шаблона для предполагаемых классов, ибо потом этого сделать уже никак не получится. А второе - очень полезная штука тогда, когда некоторые типы, используемые в шаблоне, могут кардинально отличаться от остальных. Например, значения и указатели на значения. |
|||
|
||||
| bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 85 Всего: 196 |
Fynivx, подобное делают для выведения наиболее часто используемых типов шаблонов в отдельную библиотеку. Но это не отменяет необходимости включения полного кода шаблона во все единицы компиляции, в которых он используется. А дублирования кода в пределах одной цели не будет, так как спецификатор inline четко определяет, что невстраиваемый код будет только в единственном экземпляре в результирующем бинарнике.
|
|||
|
||||
| Fynivx |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 72 Регистрация: 13.8.2011 Репутация: нет Всего: 1 |
bsa, вообще-то спецификатор inline работает с точностью до наоборот - он говорит компилятору вставлять вместо вызова функции ее код везде, где она используется...
А инстанцинирование как раз отменяет необходимость реализации функции в каждой "единице компиляции", как вы выразились. Я пробовал. Честно. Оно для этого и придумано. |
|||
|
||||
| Fynivx |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 72 Регистрация: 13.8.2011 Репутация: нет Всего: 1 |
Рассматривал спецификации 11х плюсов и заметил - теперь, при реализации в хэдере или в нескольких файлах, там, где предполагается дублирование, для его избежания при инстанцинировании можно использовать спецификатор extern - как с переменными.
Но старый способ уж точно более элегантен. |
|||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 79 Всего: 250 |
||||
|
||||
| bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 85 Всего: 196 |
Да. для этого и придумано. Но вот только где гарантии, что ты вместо int не захочешь использовать BigInt? Именно поэтому и нужен полный код шаблона. Языки С/С++ позволяют многое, но очень часто из-за этой либеральности возникают серьезные проблемы. |
|||
|
||||
| Fynivx |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 72 Регистрация: 13.8.2011 Репутация: нет Всего: 1 |
Нет такой фичи. Просто встраиваемые функции в некоторых условиях можно переопределять, в связи с чем существует заблуждение, что они решают эту проблему. Вот и всё. Но если, по каким-то причинам, функция не будет встраиваемой (ведь, по-вашему, это возможно), во время линковки возникнет варнинг, подобный тому, что написан в начале поста. В лучшем случае. А инстанцинирование необходимых шаблонов необходимо и является, как минимум, примером хорошего тона. Реализация же чего-либо, размером больше строчки, в хедерах - симптом быдлокодинга, извините. Это сообщение отредактировал(а) Fynivx - 11.3.2012, 18:44 |
|||
|
||||
| volatile |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2107 Регистрация: 7.1.2011 Репутация: 16 Всего: 85 |
||||
|
||||
| bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 85 Всего: 196 |
ты видимо начитался книг (но не понял их) и считаешь себя гуру в С++. Но есть одна книга, на которую нужно ссылаться делая подобные утверждения - это стандарт языка С++.
Источник: ISO/IEC 14882:2011 Programming Language C++ - draft Это сообщение отредактировал(а) bsa - 12.3.2012, 01:02 |
|||
|
||||
| Fynivx |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 72 Регистрация: 13.8.2011 Репутация: нет Всего: 1 |
bsa,
Я совершенно не считаю себя гуру. А еще не понимаю, что из того, что там написано опровергает то, что написал я. Inline применяется для рекомендации а не для однозначного встраивания. С этим я затупил. Да. Но второе абсолютно ничего не доказывает. Просто декларация inline автоматически внешней не сделается и, более того, реализация в заголовке не будет внешней нигде, где будет использоваться. А декларация, как внешней, 100% вызовет ошибку линковки, ибо символа нигде не будет. Напомню, что для функций внешняя декларация - это прототип. Для шаблона - template<typename T>( args ) в месте реализации либо extern template<typename T>( args ) в любом месте кода. Добавлено через 7 минут и 15 секунд volatile Ну, это отдельная тема) в STL просто нет другого выбора - они обязаны поддерживать пользовательские типы, как, впрочем, и , буст. Другим способом этого сделать нельзя, к сожалению. И вряд-ли такая возможность появится в ближайшее время( |
|||
|
||||
| bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 85 Всего: 196 |
когда ты делаешь определение шаблона в хидере, который подключаешь в нескольких единицах трансляции, то в каждой из этих единиц будет невстроенный экземпляр кода для этого шаблона (если он, конечно, в этом модуле используется). На этапе линковки лишние экземпляры будут отрезаны. Если бы этого не было, то было бы нарушение стандарта. |
|||
|
||||
![]()
|
| Правила форума "C/C++: Для новичков" | |
|
|
Запрещается! 1. Публиковать ссылки на вскрытые компоненты 2. Обсуждать взлом компонентов и делиться вскрытыми компонентами
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C/C++: Для новичков | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |