параметр наследуется от некоторого шаблонного класса?
Получить в плане?
template <typename T> class UdpServer { }; template <typename T, typename R> class UdpServer<IController<T,R>> { по понятным причинам это не будет работать, но нужно чтобы эта специализация касалась всех наследников IController
Все ещё непонятно в чем проблема
нужно сделать эту специализацию, как ещё объяснить?
Если я правильно понял с условием наследования
уже думал про свиную, но не пойму куда её всунуть(
template <typename T> class UdpServer { }; template <typename T, typename = std::enable_if_t<std::is_base_of<IController, T>>> class UdpServer<T> {}; Что-нибудь такое. Только проблема в том, что видимо IController тоже шаблонный и там могут быть разные параметры
IController шаблонный, и эти параметры шаблона нужно бы получить тоже
Ну ты их не выведешь из типа наследника. Так что никак. Либо какой-нибудь тэг вводить.
struct Der : public IController<int, int>, IControllerTag {}; Может есть что адекватнее
IControllerTag можно в IController запихнуть в наследовании
тоже склоняюсь что никак, всегда считал что шаблоны могут все(
Ну вот тебе вариант как это решить
Шаблоны могут почти всё. Механизм вывода типов - нет
Вы тоже считаете что в общем виде это не разрешимо?
struct IControllerTag{}; template<class, class> struct IController : IControllerTag {}; template <typename T> class UdpServer { }; template <typename T, typename = std::enable_if_t<std::is_base_of<IControllerTag, T>>> class UdpServer<T> {};
Хз чем тебя не устраивает такое решение
Ну не получим же параметры IController
Через тайпдефы внутри класса?
Получить параметры - не проблема. Концепты доступны, кстати?
Для этого же скастовать нужно?
https://godbolt.org/z/Maj1o1hPs нет вроде
https://godbolt.org/z/6qvsK7Mfs https://godbolt.org/z/o7P996fch Реализация без тегов
Не подумал как-то
https://godbolt.org/z/7jGq4a59G не подскажите Александр, почему тут сфинае не врубается?
template<typename TT> struct UDPServer<TT, decltype(carg(std::declval<TT&>()), void()), decltype(cret(std::declval<TT&>()), void())> { using in_t = decltype(carg(std::declval<TT&>())); using out_t = decltype(cret(std::declval<TT&>())); };
template<typename TT, typename=void> struct UDPServer {} ; template<typename TT> struct UDPServer<TT, std::void_t<decltype(carg(std::declval<TT&>())), decltype(cret(std::declval<TT&>()))>> { using in_t = decltype(carg(std::declval<TT&>())); using out_t = decltype(cret(std::declval<TT&>())); }; Нет?
А есть вариант же не засорять шаблонные параметры
До концептов без , typename = void> не обойтись, как я знаю
А вообще, точно ли тут нужно SFINAE? Если нужно просто фейлить компиляцию для всех контроллеров, которые не IController<T, U>, то вся эта мешанина не нужна
цель реализовать контроллер у которого шаблонный аргумент наследник IController и при этом заиметь параметры этого IController
Тогда достаточно template <typename TT> struct UDPServer { using in_t = decltype(carg(std::declval<TT&>())); using out_t = decltype(cret(std::declval<TT&>())); };
мне теперь не дает покоя другое, что в decltype в конце должен быть , void()
void() в моём примере нужен, чтобы decltype(...) в итоге вычислялся в void и специализация вычислилась в UDPServer<TT, void, void>, а не в какое-нибудь UDPServer<TT, int, float>
а чем UDPServer<TT, int, float> плох?
Тем, что это будет не та специализация. UDPServer<TT> фактически имеет тип UDPServer<TT, void, void> благодаря дефолтным шаблонным параметрам, что не совпадает со специализацией UDPServer<TT, int, float>
то есть когда вызываем UDPServer<AAA> то в специализации шаблонные параметры после разворачивания обязательно должны совпадать с базовой декларацией, где по дефолту войды, так?
Совпадать не обязаны. Просто когда ты пишешь UDPServer<AAA>, ты фактически получаешь UDPServer<AAA, void, void>, где void достаются из дефолта. Дальше компилятор пытается сматчить специализацию, но не может, т.к. у неё не void'ы, а int и float.
с ума сойти, не знал, спасибо
Обсуждают сегодня