Есть функция, которая использует один из двух классов потомков и вызывается через std::thread(MyFunc, std::ref(SpecifiedClassType)).detach()
У класса-родителя нет некоторых методов потомков, поэтому объявлять объекты потомков типом родителя не вариант.
Можно ли как-то указать какие именно классы могут быть переменной в этой функции, или кроме template
Пояснение:
Есть класс Capture у которого два потомка - Camera и Screen. Назначение этой системы - получение кадров с камеры или скриншотов экрана - и более ничего (сети там быть не должно). У родителя есть общая для потомков функция GrabJPG, которая вызывается во внешней функции, в потоке. Я хочу, чтобы та функция MyFunc, что я упомянул в начале темы, выглядела примерно так:
void StreamThread(STREAMER &cgf, <только_тип_Camera_или_Screen> &source){
// где cfg - структура с параметрами сетевой конфигурации,
// а source - источник кадров - камера или экран.
// ...
cgf.connection->open(cgf.host, cgf.port)
// ... туда-сюда настройки
while (cgf.connection->active()){
// ...
int size = source->GrabJPG(&buffer);
if( size){ cgf.connection->transmit(buffer, size); }
// ...
}
}
Сейчас у меня два таких абсолютно одинаковых StreamThread-а, различающихся только одной переменной - классом камеры или экрана. Не красиво, согласитесь? Должна быть ошибка компиляции, если попытаться засунуть в функцию любой другой класс, не являющийся потомком Capture. Вот, что требуется.
Ответ
Есть несколько подходов к решению подобной проблемы:
Явное инстанцирование
+ Определения для обоих вариантов StreamThread будут сгенерированы автоматически на основе общего шаблонного кода с помощью директив явного инстанцирования (в том файле, где эти директивы будут указаны).
+ (C++11 и выше) Неявное инстанцирование шаблона функции StreamThread для шаблонных аргументов Camera и Screen можно запретить во всех единицах трансляции, куда будет подключен заголовочный файл StreamThread.h
– При попытке скомпилировать функцию StreamThread со значением шаблонного аргумента, отличного от Camera или Screen, будет выдана ошибка линковки (а не компиляции).
// StreamThread.h
template
extern template void StreamThread(SREAMER &cgf, Camera &source); // C++11 и выше
extern template void StreamThread(SREAMER &cgf, Screen &source); // C++11 и выше
// StreamThread.cpp
template
template void StreamThread(SREAMER &cgf, Camera &source);
template void StreamThread(SREAMER &cgf, Screen &source);
Ограничение множества типов, которые могут использоваться в качестве аргумента шаблона, с помощью SFINAE
При использовании данного подхода будут выдаваться ошибки компиляции в случае несовпадения аргумента шаблонной функции с Camera или Screen
// StreamThread.h
#include
template
Комментариев нет:
Отправить комментарий