k155la3 26 11 января, 2017 Опубликовано 11 января, 2017 · Жалоба Проект многомодульный, и полно "перекрестных" запросов из модуля в модуль. В классе есть функция-метод, заданная шаблоном. Этот класс предполагаетс пользовать из других модулей. Где должно располагаться "тело" функции, в hpp-файле или в cpp ? (как шаблон "узнает" какие "сущности-реализации" кода шаблона-функции надо генерировать, если это все (запросы к ф-ии из других модулей) проясняется уже на уровене линкера, и "докомпилировать" уже нельзя). Я пришел к выводу, что код надо размещать в hpp-файле, который включается во все вызывающие модули. Это так или нет ? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 119 11 января, 2017 Опубликовано 11 января, 2017 · Жалоба Где должно располагаться "тело" функции, в hpp-файле или в cpp ? В заголовочном файле. если это все (запросы к ф-ии из других модулей) проясняется уже на уровене линкера, и "докомпилировать" уже нельзя).Нет, это разрешается на этапе компиляции. Линкер только из нескольких одинаковых реализаций в разных единицах трансляции оставляет одну. В .cpp можно поместить специализацию, но в заголовочном файле в этом случае должно быть указано, что такая специализация существует. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
k155la3 26 11 января, 2017 Опубликовано 11 января, 2017 · Жалоба В заголовочном файле. . . . . Спасибо за инф. Все ясно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sigmaN 0 12 января, 2017 Опубликовано 12 января, 2017 · Жалоба В .cpp можно поместить специализацию, но в заголовочном файле в этом случае должно быть указано, что такая специализация существует. Имеется ввиду "использование" шаблона? т.е. в .cpp например объявляем переменную templClass<char> charTemplateVar; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 119 12 января, 2017 Опубликовано 12 января, 2017 · Жалоба Имеется ввиду "использование" шаблона? т.е. в .cpp например объявляем переменную templClass<char> charTemplateVar; нет, имеется ввиду если есть заголовочный файл с шаблоном template<typename T> void func(T & data) { data = 0; } и мы хотим отдельный вариант для T = uint8_t template<> void func(uint8_t & data) { data = 1; } то если мы эту полную специализацию поместим в заголовочный файл и заголовочный файл включим в несколько исходников, то получим ошибку линковки "multiple definition of `void func<unsigned char>(unsigned char&)'" А если поместим ее в .cpp файл, то в других файлах эта специализация использована не будет, а в этом файле если она используется до определения, получим ошибку компиляции "error: specialization of 'void func(T&) [with T = unsigned char]' after instantiation". Поэтому в заголовочный файл надо поместить template<> void func(uint8_t & data); а саму реализацию уже в .cpp: template<> void func(uint8_t & data) { data = 1; } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
k155la3 26 16 января, 2017 Опубликовано 16 января, 2017 · Жалоба Имеется ввиду "использование" шаблона? т.е. в .cpp например объявляем переменную templClass<char> charTemplateVar; Задача - писать в архив(ы) записи различных форматов соотв-их, например, различным событиям или лог-записям. Автоматизация/аналог ручного использования reinterpret_cast. --------------- Events.hpp ------------------ class CLog { . . . . . int Put_SER_PageFlash_E( int ); метод записи для событий вида LOG . . . . . }; class CEvents32 { . . . . . int Put_SER_PageFlash_E( int ); метод записи для "флаговых" событий . . . . . }; ---------------- Archive.hpp -------------------- class CArchive { public: . . . . . . . . . . . . . . . template <typename TPL_EventT> int PutToArchive_B( int n, TPL_EventT * obj_ptr ) { a_page = buf_base + p_WR; ret_45 = AT45_PageIsEmpty( a_page , 264, 1); // Empty == 1 ? if( ret_45 != 1 ) return(-200); else { ret_45 = obj_ptr->Put_SER_PageFlash_E( a_page ); if( ret_45 > 0 ) { ForwardIndex(); return(1); } else return(ret_45); } } . . . . . . . . CArchive( int r_size ) { . . . . . }; ~CArchive(void) { }; }; ----------- вызовы из модулей ------------- (1) модуль 1 // тип Type(EV_Alarm32_1) == CEvents32 retCode_2 = ARH_Event.PutToArchive_B( 0, &EV_Alarm32_1); пишем флаги 32 бит (2) модуль 2 // тип Type(EV_Log_1) == CLog retCodeARH = ARH_Event.PutToArchive_B( 1, &EV_Log_1 ); пишем литерал Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться