Вот немного метапрограммирования шаблонов. is_template_instance
принимает шаблон, который принимает только типы и тип, и возвращает true, если этот второй тип является экземпляром первого шаблона.
template<template<class...>class Z, class T>
struct is_template_instance:std::false_type{};
template<template<class...>class Z, class...Ts>
struct is_template_instance<Z,Z<Ts...>>:std::true_type{};
Теперь мы хотим запросить тип значения итератора. Мы можем использовать std::iterator_traits
непосредственно, или использовать псевдоним, как это:
template<class It>
using it_value_type = typename std::iterator_traits<It>::value_type;
Составим два выше, чтобы написать is_point_iterator
шаблон:
template<class It>
using is_point_iterator = is_template_instance< Point, it_value_type<It> >;
Обратите внимание, что если вы передаете это не-итераторы, оно может не сработает в дружеской манере или может вернуть неверный результат (std::iterator_traits
не гарантирует разумные значения возврата для неитераторов).
Но это, как правило, попадает в тела шаблонов.
template<class PointIterator,
class=std::enable_if_t< is_point_iterator<PointIterator>::value >
>
void functionThatOperatesOnPointSequence(PointIterator begin, PointIterator end) {
// ...
}
существует только ограниченная полезность.
Вы можете извлечь тип значения из PointIterator в более SFINAE дружественной манере, например:
template<class It>
using it_value_type = std::decay_t<decltype(*std::declval<It>())>;
, если вам нужна поддержка SFINAE.
Вы что-то создали? Это переполнение стека, поэтому вы должны задать вопрос, указав, что вы приложили некоторые усилия. Не запрашивайте готовое решение. – sebap123
'PointIterator :: operator *' может возвращать только один тип объектов. «PointIterator» должен быть аргументом шаблона. – user2079303
'is_a_point> :: value'? –
Jarod42