Если у меня есть тип T
, какой полезный способ проверить его во время компиляции, чтобы увидеть, является ли он контейнером в стиле STL (для произвольного типа значения) или нет?
(Предположение: указатели, ссылки и т. Д. Уже удалены)
Стартовый код:
template<class T> // (1)
void f(T&) {}
template<class T> // (2)
void f(std::vector<T>&) {}
void test()
{
int a;
std::vector<int> b;
f(a);
f(b);
}
Теперь это работает нормально, но что, если я хочу обобщить контейнер (т.е. не определять (3) , (4) , ... явно)?
Использование SFINAE и списков типов несколько уменьшит код, но есть ли лучший способ?
Или есть идиома специализации, основанная на понятиях?
Или я мог бы как-то использовать SFINAE для выборочного включения только желаемых специализаций?
В качестве идентификатора я не могу использовать итераторы - я пытаюсь специализироваться на основе функций, которые получают T
s в качестве параметров.
Согласно MSalters ответ :
template<class T>
void f(T&, ...) {
std::cout << "flat" << std::endl;
}
template<class Cont>
void f(Cont& c, typename Cont::iterator begin = Cont().begin(),
typename Cont::iterator end = Cont().end()) {
std::cout << "container" << std::endl;
}
(Переменный список аргументов необходим, чтобы первая f
была наименее предпочтительной версией для решения ошибок неоднозначности)