Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.88/25: Рейтинг темы: голосов - 25, средняя оценка - 4.88
 Аватар для NoobsEnslaver
136 / 48 / 2
Регистрация: 31.07.2014
Сообщений: 238

Переопределение метода класса-шаблона

04.09.2014, 21:57. Показов 5059. Ответов 20
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Привет народ. Есть такой код:
C++
1
2
3
4
5
6
typedef OS::process<OS::pr0, 90> TProc1;
TProc1 Proc1;
template<> void Proc1::exec()
{
    //тут кот
}
Можете объяснить как это работает? А если точнее, зачем при переопределении функции класса proc писать tamplate<>? И, я правильно понимаю - здесь есть класс proc, в нем виртуальный метод exec(). Класс построен на шаблоне - в нем указывается два параметра, в данном случае это приоритет и размер стека. Мы для удобства делаем typedef, чтобы обозвать данный набор параметров, а потом создаем объект класса, которому переопределяем метод exec(). Я всё правильно понимаю?
0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
04.09.2014, 21:57
Ответы с готовыми решениями:

Определение метода-шаблона за пределами шаблона класса
День добрый! Разбираюсь в шаблонах, решил копнуть поглубже. Вот пример: template &lt;typename T1&gt; class K // шаблон класса { ...

Синтаксис определения метода специализии шаблона класса.
Есть некий шаблон класса: template &lt;typename T1, typename T2, typename T3&gt; class А { }; Есть специализация этого шаблона и в нём некий...

Вынос реализации метода шаблона класса в другой файл
Здравствуйте! Допустим, есть класс: // class.hpp #ifndef CLASS_HPP_ #define CLASS_HPP_ class testClass{ public:

20
:)
Эксперт С++
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
04.09.2014, 22:16
Вообще-то, тут что-то не логичное. TProc1 - синоним типа OS::process<OS::pr0, 90>. Proc1 - стало быть экземпляр этого типа. И третья строка совсем этим не стыкуется. То же самое, что написать:
C++
1
2
SomeClass a;
a::f(){} // Должен быть тип, а не экземпляр класса
0
 Аватар для NoobsEnslaver
136 / 48 / 2
Регистрация: 31.07.2014
Сообщений: 238
04.09.2014, 22:21  [ТС]
Тем не менее - это строчка из примера для запуска процесса операционки scmRTOS (для микроконтроллеров, но C++ он и в Африке).
0
:)
Эксперт С++
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
04.09.2014, 22:28
NoobsEnslaver, ссылку на пример можно увидеть?
0
 Аватар для NoobsEnslaver
136 / 48 / 2
Регистрация: 31.07.2014
Сообщений: 238
04.09.2014, 22:38  [ТС]
Вот ссылка на sourceforge:
http://sourceforge.net/project... r/download
Там зайти в AVR\GCC\MEGA\3-Channel\main.c
Или вот, именно кусочек того что тебе нужно, чтобы не рыться:
https://cloud.mail.ru/public/8... %2FMEGA.7z
0
Модератор
Эксперт JS
 Аватар для Eva Rosalene
5241 / 2115 / 416
Регистрация: 06.01.2013
Сообщений: 4,846
04.09.2014, 22:59
NoobsEnslaver, либо ссылка не та, либо что-то совсем странное. Ибо я вижу только пример с Тип::метод
0
 Аватар для NoobsEnslaver
136 / 48 / 2
Регистрация: 31.07.2014
Сообщений: 238
04.09.2014, 23:35  [ТС]
Ну как же, точно 3-Channel\src\main.c смотрел?
Вот оттуда фрагменты:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
...
//      Process types
//
typedef OS::process<OS::pr0, 120> TProc1;
typedef OS::process<OS::pr1, 160> TProc2;
typedef OS::process<OS::pr2, 120> TProc3;
 
//---------------------------------------------------------------------------
//
//      Process objects
TProc1 Proc1;
TProc2 Proc2;
TProc3 Proc3;
...
template<> void TProc1::exec()
{
    DRIVER(PROC1,OUT);
    DRIVER(TIMER1_TO_PROC1,OUT);
    for(;;)
    {
        OFF(PROC1);
        Timer1_Ovf.Wait();
        ON(PROC1);
        OFF(TIMER1_TO_PROC1);
        SlonQueue.push(&African);
    }
} // TProc1::exec()
 
} // namespace OS
0
5500 / 4895 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
04.09.2014, 23:57
Цитата Сообщение от NoobsEnslaver Посмотреть сообщение
Вот оттуда фрагменты:
Сравним. Первый пост:
Цитата Сообщение от NoobsEnslaver Посмотреть сообщение
C++
1
2
template<> void Proc1::exec()
{
7 пост:
Цитата Сообщение от NoobsEnslaver Посмотреть сообщение
C++
1
2
template<> void TProc1::exec()
{
0
 Аватар для NoobsEnslaver
136 / 48 / 2
Регистрация: 31.07.2014
Сообщений: 238
05.09.2014, 00:02  [ТС]
Да да да... недосмотрел я эту Т Спасибо) Ну ладно, а дальше по сабжу - я правильно истолковал, кроме момента с потерянной "Т" код? И еще - зачем при переопределении exec() вначале ставится template<>? Не совсем понимаю этот механизм..
0
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,816
05.09.2014, 01:42
Цитата Сообщение от NoobsEnslaver Посмотреть сообщение
И еще - зачем при переопределении exec() вначале ставится template<>? Не совсем понимаю этот механизм..
Затем, что OS:: process - это шаблон.
А
C++
1
template<> void TProc1::exec()
можно переписать так:
C++
1
template<> OS::process<OS::pr0, 120>::exec()
Это явная специализация (явное инстанцирование) метода шаблонного класса. Используется для повышения эффективности кодогенерации (иначе такая функция будет генерироваться в каждой единице трансляции, где инстанцируется шаблон). Обрати внимание, что в заголовочном файле специально оставлено только определение этого метода. Если мы попытаемся инстанцировать OS:: process какими-то другими аргументами, отличными от явно специализированных, то получим ошибку линковщика.
0
5500 / 4895 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
05.09.2014, 02:00
Цитата Сообщение от DrOffset Посмотреть сообщение
явное инстанцирование
А разве у явного инстанцирования такой синтаксис?
Миниатюры
Переопределение метода класса-шаблона  
0
 Аватар для NoobsEnslaver
136 / 48 / 2
Регистрация: 31.07.2014
Сообщений: 238
05.09.2014, 09:06  [ТС]
Всётаки еще не понятно - во-первых почему вначале мы ставим template<>, хотя дальше у нас и так идет конкретизация шаблона <OS:r0, 120>, во-вторых - не возникнет проблем из за того, что мы сначала создали объект класса, а потом переопределили ему метод? И в-третьих, ну эт немного по-нубски, но всёже - разве создание объекта класса происходит не так
C++
1
TProc1 Proc1 = new TProc();
0
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,816
05.09.2014, 10:32
Лучший ответ Сообщение было отмечено NoobsEnslaver как решение

Решение

Цитата Сообщение от alsav22 Посмотреть сообщение
А разве у явного инстанцирования такой синтаксис?
Это специализация функции шаблона. Явное инстанцирование тут происходит вследствие нее.
Явно инстанцировать такой метод можно несколькими способами.
Первый способ написать явное инстанцирование для всего класса
C++
1
2
3
4
5
6
7
8
template <typename T1, typename T2>
class A
{
public:
    void foo();
};
 
template class A<int, int>; // explicit istantiation
Можно также инстанцировать конкретную функцию
C++
1
template void A<int, int>::foo();
но для того, чтобы это работало, должно быть доступно определение этого шаблонного метода
C++
1
2
3
4
template <typename T1, typename T2>
void A<T1, T2>::foo()
{
}
причем, если мы напишем
C++
1
2
3
template void A<int, int>::foo();
template void A<int, double>::foo();
template void A<int, short>::foo();
то он сгенерирует три функции, но по одному шаблону. В примере ТС ситуация другая: нужно явное инстанцирование для разных реализаций exec.
Поэтому мы воспользовались специализией (но явное инстанцирование от этого не перестало происходить).
C++
1
2
3
4
template <>
void A<int, int>::foo()
{
}
Отвечая на вопрос ТС, зачем там скобочки: такой синтаксис принят, чтобы обозначить, что это полная специализация. Потому что может быть еще и частичная (которая не приводит к явному инстанцированию, поэтому для нее должен быть доступен и частично специализированный шаблон):
C++
1
2
3
4
5
6
7
8
9
10
11
template <typename T>
class A<T, int>
{
public:
    void foo();
};
 
template <typename T>
void A<T, int>::foo()
{
}
Добавлено через 4 минуты
Цитата Сообщение от NoobsEnslaver Посмотреть сообщение
не возникнет проблем из за того, что мы сначала создали объект класса, а потом переопределили ему метод?
Вот такая запись же тебя не смущает:
C++
1
2
3
4
5
6
7
8
9
10
void foo();
 
int main()
{
    foo();
}
 
void foo()
{
}
Так почему в рассматриваемом случае должно?
Цитата Сообщение от NoobsEnslaver Посмотреть сообщение
разве создание объекта класса происходит не так
Ты привел пример создания объекта в куче (heap). Это не единственный способ.
4
5500 / 4895 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
06.09.2014, 01:13
Цитата Сообщение от NoobsEnslaver Посмотреть сообщение
И в-третьих, ну эт немного по-нубски, но всёже - разве создание объекта класса происходит не так
C++
1
TProc1 Proc1 = new TProc();
C++
1
2
TProc1* Proc1 = new TProc(); // объект создаётся в динамической памяти (куче), возвращается указатель на эту память.
TProc1 Proc1; // объект создаётся в автоматической памяти (на стеке)
Добавлено через 11 часов 32 минуты
Цитата Сообщение от DrOffset Посмотреть сообщение
Поэтому мы воспользовались специализией (но явное инстанцирование от этого не перестало происходить).
DrOffset, я правильно понял, что явное инстанцирование функции происходит тогда, когда компилятор встречает именно определение явной специализации, а не объявление (в отличие от такого явного инстанцирования:
C++
1
template void A<int, int>::foo();
)?
0
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,816
06.09.2014, 01:29
Цитата Сообщение от alsav22 Посмотреть сообщение
в отличие от такого явного инстанцирования
Такое инстанцирование всегда требует наличие доступного определения в данной единице трансляции (без него оно не должно компилироваться). Поэтому чисто технически нет никакой разницы. Разница в примере ТС в том, что мы явно инстанцировали три разные версии функций (в смысле с разным телом), использовав явную специализацию функции. В отличие от инстанцирования трех одинаковых (в смысле по одному и тому же шаблону) функций, в случае использования такого синтаксиса:
C++
1
2
3
template void A<int, int>::foo();
template void A<int, short>::foo();
template void A<int, char>::foo();
0
5500 / 4895 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
06.09.2014, 01:48
Цитата Сообщение от DrOffset Посмотреть сообщение
без него оно не должно компилироваться
Компилируется, но экземпляр шаблона, как я понял, не создаётся (студия 10).
Цитата Сообщение от DrOffset Посмотреть сообщение
Такое инстанцирование всегда требует наличие доступного определения в данной единице трансляции
И то и другое требует этого. Но:
Цитата Сообщение от alsav22 Посмотреть сообщение
я правильно понял, что явное инстанцирование функции происходит тогда, когда компилятор встречает именно определение явной специализации, а не объявление?
Добавлено через 5 минут
Я почему прицепился: подумал, что в 10 посте приведены объявления специализаций, и написано:
Цитата Сообщение от DrOffset Посмотреть сообщение
Это явная специализация (явное инстанцирование) метода шаблонного класса
0
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,816
06.09.2014, 02:05
Цитата Сообщение от alsav22 Посмотреть сообщение
подумал, что в 10 посте приведены объявления специализаций, и написано:
Объявление и определение - это не одно и то же.
Объявление там в основном шаблоне, вынесено в h-файл. Определения там три, для каждой специализации. Но т.к. специализация явная, то она приводит к инстацированию (генерации) функций. Я специально указал сперва синтаксическое определение, а затем в скобочках эффект, который при этом достигается. Этого собственно и добивался автор. Вызов метода exec из другой единицы трансляции не будет приводить к инстацированию, вместо этого будут использованы уже инстацированные функции из модуля, который мы тут рассматривали.
Я понимаю, что тебя сбило с толку не "книжное" изложение материала. Но это не расходится с теорией, т.к. механизмы все взаимосвязаны и здесь важно понимать что именно происходит при тех или иных действиях, а не просто запоминать и ассоциировать поведение с определенным синтаксисом.

Добавлено через 5 минут
Цитата Сообщение от alsav22 Посмотреть сообщение
Компилируется, но экземпляр шаблона, как я понял, не создаётся (студия 10).
Да, сейчас попробовал в 2012 студии, выдал только warning:
warning C4661: void A<T1,T2>::foo(void): отсутствует подходящее определение для запроса на явное создание экземпляра шаблона
Цитата Сообщение от alsav22 Посмотреть сообщение
явное инстанцирование функции происходит тогда, когда компилятор встречает именно определение явной специализации, а не объявление?
Да.
1
5500 / 4895 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
06.09.2014, 02:13
Цитата Сообщение от DrOffset Посмотреть сообщение
Объявление и определение - это не одно и то же.
Объявление там в основном шаблоне, вынесено в h-файл.
Нет. Там в main.cpp объявления специализаций прописаны:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//---------------------------------------------------------------------------
//
//      Process types
//
typedef OS::process<OS::pr0, 120> TProc1;
typedef OS::process<OS::pr1, 160> TProc2;
typedef OS::process<OS::pr2, 120> TProc3;
 
// Explicit specialization of function must precede its first use. But ...
// avoid GCC bug ( [url]http://gcc.gnu.org/bugzilla/show_bug.cgi?id=15867[/url] )
#if 0
    template<> void TProc1::exec();
    template<> void TProc2::exec();
    template<> void TProc3::exec();
#endif
Добавлено через 7 минут
Цитата Сообщение от DrOffset Посмотреть сообщение
Я понимаю, что тебя сбило с толку не "книжное" изложение материала.
Нет, меня сбило то, что я неправильно понял код из 10 поста, подумал, что там приведено объявление специализаци,
и дальше написано:
Цитата Сообщение от DrOffset Посмотреть сообщение
Это ... явное инстанцирование
, что не так, так как:
Цитата Сообщение от DrOffset Посмотреть сообщение
Сообщение от alsav22 явное инстанцирование функции происходит тогда, когда компилятор встречает именно определение явной специализации, а не объявление?

Да.
0
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,816
06.09.2014, 02:21
Цитата Сообщение от alsav22 Посмотреть сообщение
Нет. Там в main.cpp объявления специализаций прописаны:
typedef - Это не объявления.
Или ты про то, что в #if 0?

Добавлено через 3 минуты
Цитата Сообщение от alsav22 Посмотреть сообщение
что не так, так как:
Это еще почему? Что-то от тебя ускользнула похоже мысль.
Определение явной специализации, вот оно:
C++
1
2
3
4
5
template <>
void A<int, int>::foo()
{
   //...
}
И тут же явное инстацирование.
0
5500 / 4895 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
06.09.2014, 02:25
Цитата Сообщение от DrOffset Посмотреть сообщение
Или ты про то, что в #if 0?
Да.

Добавлено через 3 минуты
Цитата Сообщение от DrOffset Посмотреть сообщение
Что-то от тебя ускользнула похоже мысль.
DrOffset, это от тебя моя мысль ускальзывает.
Давай так. Если было бы вот так написано, это было бы правильно?
C++
1
template<> OS::process<OS::pr0, 120>::exec(); // Здесь происходит явное инстанцирование метода шаблонного класса.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
06.09.2014, 02:25
Помогаю со студенческими работами здесь

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

Переопределение виртуального метода
Нужно написать виртуальный метод в родительском классе , который находит площадь круга. Затем переопределить этот виртуальный метод в...

Наследование. Переопределение метода родителя
не работает конструкция вида: class AllFigureData { protected: int id; int x; int y; public: virtual void getdata(); };

Вызов метода класса из метода другого класса
Помогите школнегу Имеется несколько классов class Com { protected: unsigned char bufrd, bufwr; unsigned char tx_index,...

Явное создание экземпляра класса и явная специализация шаблона класса
Всем добрый день! Не могу разобраться - эти две технологии дают один и тот же результат? В каких случаях применять одно и другое?...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru